python多处理/线程代码提前退出

时间:2016-07-13 16:01:14

标签: python multithreading python-3.x python-multiprocessing

我正在尝试创建多个进程,每个进程调用多个线程。 我正在使用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次)。

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

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

在我阅读多处理文档后,我认为这个问题是: 连接状态的文档:“阻塞调用线程,直到调用join()方法的进程终止或直到发生可选超时。”

如果按照我预期的那样工作,那么主要会在尝试加入时永远等待。

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

我尝试将“dumb”类传递给队列并传递异常,但队列保持为空。

有关如何调试此功能的任何提示将不胜感激。我最好的猜测是

  • 线程提前退出(while循环后的打印语句从未被打过)

  • 主要退出并且进程被终止

  • 加入是否正常,但不是我期望的方式?

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

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

的副本关闭 唉,没有简单,令人满意的解释“为什么”。原因是multiprocessing通过调用os._exit()而不是普通的sys.exit()来安排工作进程离开Python。 os._exit()跳过所有“正常”关机处理。跳过的部分是.join() - 非守护程序线程,因此当线程仍然在运行时,进程就会消失

至少应该(根据我)记录,或者最好改变。

与此同时,正如您所知,解决方法是自己明确地.join()线程。

另一种方式

在Python 3.4或更高版本中,您还可以使用multiprocessing的{​​{1}}启动方法:

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

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

.join()是Windows上可用的唯一启动方法,它解释了为什么我在运行原始示例时没有问题。