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 队列并传递异常,但队列保持为空。
任何关于如何调试它的提示都将不胜感激。我最好的猜测是
线程提前退出(虽然从未命中 while 循环后的打印语句)
主程序退出,进程被杀死
加入工作正常,但不是我期望的那样?
有什么想法吗?
解决方案:新错误已作为 http://bugs.python.org/issue18966
的副本关闭
唉,没有简单、令人满意的解释 "for why"。原因是 multiprocessing
通过调用 os._exit()
而不是正常的 sys.exit()
安排工作进程离开 Python。 os._exit()
跳过所有 "normal" 关机处理。跳过的部分内容是 .join()
-ing 非守护线程,因此进程消失 而 线程仍然 运行.
至少(根据我的看法)应该记录下来,或者最好更改一下。
与此同时,解决方法 - 如您所知 - 是自己显式 .join()
线程。
另一种方式
在 Python 3.4 或更高版本下,您还可以使用 multiprocessing
的 spawn
启动方法:
https://docs.python.org/3/library/multiprocessing.html?highlight=spawn#contexts-and-start-methods
这会导致工作进程通过 sys.exit(exitcode)
完成,它会执行所有正常的关闭处理(包括 .join()
-ing 非守护线程)。
spawn
是仅 在Windows 上可用的启动方法,这解释了为什么我没有问题运行 你的原始示例。
我正在尝试创建多个进程,每个进程调用多个线程。 我 运行 以下代码 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 队列并传递异常,但队列保持为空。
任何关于如何调试它的提示都将不胜感激。我最好的猜测是
线程提前退出(虽然从未命中 while 循环后的打印语句)
主程序退出,进程被杀死
加入工作正常,但不是我期望的那样?
有什么想法吗?
解决方案:新错误已作为 http://bugs.python.org/issue18966
的副本关闭唉,没有简单、令人满意的解释 "for why"。原因是 multiprocessing
通过调用 os._exit()
而不是正常的 sys.exit()
安排工作进程离开 Python。 os._exit()
跳过所有 "normal" 关机处理。跳过的部分内容是 .join()
-ing 非守护线程,因此进程消失 而 线程仍然 运行.
至少(根据我的看法)应该记录下来,或者最好更改一下。
与此同时,解决方法 - 如您所知 - 是自己显式 .join()
线程。
另一种方式
在 Python 3.4 或更高版本下,您还可以使用 multiprocessing
的 spawn
启动方法:
https://docs.python.org/3/library/multiprocessing.html?highlight=spawn#contexts-and-start-methods
这会导致工作进程通过 sys.exit(exitcode)
完成,它会执行所有正常的关闭处理(包括 .join()
-ing 非守护线程)。
spawn
是仅 在Windows 上可用的启动方法,这解释了为什么我没有问题运行 你的原始示例。