我有一个multiprocessing.Pool正在运行的任务,如果通过处理SIGTERM信号来终止的话,我不会优雅地退出
这是我的代码示例(使用python3.9)
import os
import signal
import time
from multiprocessing import Pool
class SigTermException(Exception):
pass
def sigtermhandler(signum, frame):
raise SigTermException('sigterm')
def f():
print(os.getpid())
try:
while True:
print("loop")
time.sleep(5)
except SigTermException:
print("Received SIGTERM")
def main():
signal.signal(signal.SIGTERM, sigtermhandler)
pool = Pool()
pool.apply_async(f)
print("wait 5")
time.sleep(5)
print("Terminating")
pool.terminate()
print("Joining")
pool.join()
print("Exiting")
if __name__ == '__main__':
main()我本来想打印的
...
Terminating
Received SIGTERM
Joining
Exiting然而,它似乎并没有超过pool.terminate()
下面是一个例子
wait 5
92363
loop
Terminating
loop
Received SIGTERM执行ps --我看到以下内容
92362 pts/0 S+ 0:00 | | \_ python signal_pool.py
92363 pts/0 S+ 0:00 | | \_ python signal_pool.py所以看起来这个子进程仍然是“活的”
还测试了上述这里解决方案,但没有效果。
如有任何帮助的提示,我们将不胜感激。
发布于 2022-04-24 14:16:27
您的辅助函数f永远运行,但是您的主进程只休眠5秒,然后在池上调用terminate,这将导致任何正在运行的任务被终止。这与您的说法相矛盾,您希望您的任务在收到SIGTERM的情况下优雅地退出,因为按照目前的情况,在没有SIGTERM的情况下,它们不会优雅地退出。
所以我认为主要的过程应该是等待,只要有必要就完成提交的任务--这是通常的情况,对吗?当我尝试使用这个命令并发出杀死-15命令时,可能是因为主进程处于等待状态,等待提交的任务完成,而仅由worker函数处理,而信号从未传递给主进程。因此,在主要过程中,我不需要try/except块。
import os
import signal
import time
from multiprocessing import Pool
class SigTermException(Exception):
pass
def sigtermhandler(signum, frame):
raise SigTermException('sigterm')
def f():
print(os.getpid())
try:
while True:
print("loop")
time.sleep(5)
except SigTermException:
print("Received SIGTERM")
def main():
signal.signal(signal.SIGTERM, sigtermhandler)
pool = Pool()
async_result = pool.apply_async(f)
print("waiting for task to complete ...")
async_result.get() # wait for task to complete
pool.close()
print("Joining")
pool.join()
print("Exiting")
if __name__ == '__main__':
main()印刷:
waiting for task to complete ...
98
loop
Received SIGTERM
Joining
Exiting你也可以这样做:
def main():
signal.signal(signal.SIGTERM, sigtermhandler)
pool = Pool()
pool.apply_async(f)
print("waiting for all tasks to complete ...")
pool.close()
pool.join()
print("Exiting")https://stackoverflow.com/questions/71985130
复制相似问题