python Pool result.get() block 信号处理程序

标签 python multithreading multiprocessing signals

我将一些长时间运行的工作交给 Pool 并执行 result.get():

result = my_pool.apply_async(long_run_func)
result.get()

该进程将被阻塞在这里,我尝试向该进程发送信号。然后我发现信号处理程序只有在 result.get() 完成后才会被调用。

这是我运行的示例代码:

import os
import sys 
import atexit
import time
from threading import Thread
from multiprocessing import Pool
from signal import signal,SIGTERM,SIG_IGN


def func_in_pool():
    for i in range(10):
        print 'Sleeping... %d'%i
        time.sleep(1)

def func_in_atexit():
    print 'Calling from atexit()'

def func_in_thread():
    print 'Calling from thread.'
    time.sleep(4)
    print 'Calling from thread: os.kill()'
    os.kill(os.getpid(), SIGTERM)

def init_worker():
    signal(SIGTERM, SIG_IGN)

my_pool=Pool(2, init_worker)
signal(SIGTERM, lambda signum, stack_frame: sys.exit(1))
atexit.register(func_in_atexit)

mythread = Thread(target=func_in_thread)
mythread.start()
print 'Thread has been started'
result = my_pool.apply_async(func_in_pool,[])
result.get()
time.sleep(2)
print 'After get()'
mythread.join()

我预计该过程将在 4 秒后结束,但实际上它在 10 秒后结束,这意味着 result.get() 已返回。

输出如下:

python myexit.py
Calling from thread.
Thread has been started
Sleeping... 0
Sleeping... 1
Sleeping... 2
Sleeping... 3
Calling from thread: os.kill()
Sleeping... 4
Sleeping... 5
Sleeping... 6
Sleeping... 7
Sleeping... 8
Sleeping... 9
Calling from atexit()

信号处理程序确保在atexit 中注册的函数能够得到调用。如何让后台线程生成信号并立即调用信号处理程序?

(如果不将信号处理程序放在那里,当线程产生信号时,进程将结束。但是,在这种情况下,在atexit中注册的函数将不会被调用。)

最佳答案

这是由 bug 引起的在Python中。解决方法是在 get() 中指定超时——即使是很长的超时也可以:

result.get(timeout=525600*60) # It's time now, to sing out

关于python Pool result.get() block 信号处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28334737/

相关文章:

java - 当有多个线程时,跳出循环的最佳方法是什么?

python - 搜索名称并从大文件中提取相应的条目 - 最快的方法 - Python 和 Regex

python - 如何让elasticsearch执行精确匹配查询?

c# - 异步/等待内存缓存的线程安全

python - 使用列号中的条件使用 python 和 xlwt 导出到 Excel

java - 控制ExecutorService每秒最多执行N个任务

python - 如何在单独的进程中启动具有多个队列的多处理网络管理器

python - 在 Python 的子进程中生成一个线程

Jquery 和 Django 多复选框

python - 如何在 Bokeh 中同时使用对数辅助轴和线性轴?