我正在尝试创建多个进程,每个进程调用多个线程。 我正在使用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循环后的打印语句从未被打过)
主要退出并且进程被终止
加入是否正常,但不是我期望的方式?
有什么想法吗?
答案 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上可用的唯一启动方法,它解释了为什么我在运行原始示例时没有问题。