python multiprocessing/threading 代码提前退出

python multiprocessing/threading code exits early

我正在尝试创建多个进程,每个进程调用多个线程。 我 运行 以下代码 python3.5

问题的简化示例如下所示:

import multiprocessing
import time
import threading    

class dumb(threading.Thread):
    def __init__(self):
        super(dumb, self).__init__()
    def run(self):
        while True:
            print("hi")
            time.sleep(1)    

def test():
    for i in range(2):
        bar = dumb()
        bar.start()
def main():
    p = []
    for i in range(2):
        p.append(multiprocessing.Process(target=test))
    for i in p:
        i.start()
    for i in p:
        i.join()
if __name__ == '__main__':
    main()

我希望这段代码永远打印 "hi",但它只为每个进程中的每个线程打印一次(总共 4 次)。

当我删除多处理时,多线程工作。

当我删除多线程时,多处理工作。

看了multiprocessing文档后我认为是问题的部分: 加入状态的文档:"Block the calling thread until the process whose join() method is called terminates or until the optional timeout occurs."

如果它按我预期的那样工作,main 将在尝试加入时永远等待。

我在 while 循环周围放置了 try/except 块,但没有发现任何错误。

我已经尝试通过 "dumb" class 队列并传递异常,但队列保持为空。

任何关于如何调试它的提示都将不胜感激。我最好的猜测是

有什么想法吗?

解决方案:新错误已作为 http://bugs.python.org/issue18966

的副本关闭

唉,没有简单、令人满意的解释 "for why"。原因是 multiprocessing 通过调用 os._exit() 而不是正常的 sys.exit() 安排工作进程离开 Python。 os._exit() 跳过所有 "normal" 关机处理。跳过的部分内容是 .join()-ing 非守护线程,因此进程消失 线程仍然 运行.

至少(根据我的看法)应该记录下来,或者最好更改一下。

与此同时,解决方法 - 如您所知 - 是自己显式 .join() 线程。

另一种方式

在 Python 3.4 或更高版本下,您还可以使用 multiprocessingspawn 启动方法:

https://docs.python.org/3/library/multiprocessing.html?highlight=spawn#contexts-and-start-methods

这会导致工作进程通过 sys.exit(exitcode) 完成,它会执行所有正常的关闭处理(包括 .join()-ing 非守护线程)。

spawn 在Windows 上可用的启动方法,这解释了为什么我没有问题运行 你的原始示例。