首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python进程池信号处理

Python进程池信号处理
EN

Stack Overflow用户
提问于 2022-04-24 02:51:50
回答 1查看 257关注 0票数 0

我有一个multiprocessing.Pool正在运行的任务,如果通过处理SIGTERM信号来终止的话,我不会优雅地退出

这是我的代码示例(使用python3.9)

代码语言:javascript
复制
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()

我本来想打印的

代码语言:javascript
复制
...
Terminating
Received SIGTERM
Joining
Exiting

然而,它似乎并没有超过pool.terminate()

下面是一个例子

代码语言:javascript
复制
wait 5
92363
loop
Terminating
loop
Received SIGTERM

执行ps --我看到以下内容

代码语言:javascript
复制
  92362 pts/0    S+     0:00  |   |   \_ python signal_pool.py
  92363 pts/0    S+     0:00  |   |       \_ python signal_pool.py

所以看起来这个子进程仍然是“活的”

还测试了上述这里解决方案,但没有效果。

如有任何帮助的提示,我们将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2022-04-24 14:16:27

您的辅助函数f永远运行,但是您的主进程只休眠5秒,然后在池上调用terminate,这将导致任何正在运行的任务被终止。这与您的说法相矛盾,您希望您的任务在收到SIGTERM的情况下优雅地退出,因为按照目前的情况,在没有SIGTERM的情况下,它们不会优雅地退出。

所以我认为主要的过程应该是等待,只要有必要就完成提交的任务--这是通常的情况,对吗?当我尝试使用这个命令并发出杀死-15命令时,可能是因为主进程处于等待状态,等待提交的任务完成,而仅由worker函数处理,而信号从未传递给主进程。因此,在主要过程中,我不需要try/except块。

代码语言:javascript
复制
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()

印刷:

代码语言:javascript
复制
waiting for task to complete ...
98
loop
Received SIGTERM
Joining
Exiting

你也可以这样做:

代码语言:javascript
复制
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")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71985130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档