【发布时间】:2019-01-10 20:41:20
【问题描述】:
我在下面的 python 3.6.3 中编写并执行了一个简单的测试程序。它在一台 4 核的机器上执行。
import multiprocessing
import time
def f(num):
print(multiprocessing.current_process(), num)
time.sleep(1)
if (num % 2):
raise Exception
pool = multiprocessing.Pool(5)
try:
pool.map(f, range(1,20))
except Exception as e:
print("EXCEPTION")
pool.close()
pool.join()
输出pool = multiprocessing.Pool(5):
<ForkProcess(ForkPoolWorker-1, started daemon)> 1
<ForkProcess(ForkPoolWorker-2, started daemon)> 2
<ForkProcess(ForkPoolWorker-3, started daemon)> 3
<ForkProcess(ForkPoolWorker-4, started daemon)> 4
<ForkProcess(ForkPoolWorker-5, started daemon)> 5
<ForkProcess(ForkPoolWorker-2, started daemon)> 6
<ForkProcess(ForkPoolWorker-1, started daemon)> 7
<ForkProcess(ForkPoolWorker-4, started daemon)> 8
<ForkProcess(ForkPoolWorker-3, started daemon)> 9
<ForkProcess(ForkPoolWorker-5, started daemon)> 10
<ForkProcess(ForkPoolWorker-2, started daemon)> 11
<ForkProcess(ForkPoolWorker-1, started daemon)> 12
<ForkProcess(ForkPoolWorker-4, started daemon)> 13
<ForkProcess(ForkPoolWorker-3, started daemon)> 14
<ForkProcess(ForkPoolWorker-5, started daemon)> 15
<ForkProcess(ForkPoolWorker-2, started daemon)> 16
<ForkProcess(ForkPoolWorker-1, started daemon)> 17
<ForkProcess(ForkPoolWorker-3, started daemon)> 18
<ForkProcess(ForkPoolWorker-4, started daemon)> 19
EXCEPTION
但是,如果我将池的进程计数更改为等于或小于我机器上的内核数,则对 f() 的每次调用都不会打印,其中 num 是。
使用pool = multiprocessing.Pool(4) 输出:
<ForkProcess(ForkPoolWorker-1, started daemon)> 1
<ForkProcess(ForkPoolWorker-2, started daemon)> 3
<ForkProcess(ForkPoolWorker-3, started daemon)> 5
<ForkProcess(ForkPoolWorker-2, started daemon)> 7
<ForkProcess(ForkPoolWorker-1, started daemon)> 9
<ForkProcess(ForkPoolWorker-3, started daemon)> 11
<ForkProcess(ForkPoolWorker-3, started daemon)> 13
<ForkProcess(ForkPoolWorker-1, started daemon)> 15
<ForkProcess(ForkPoolWorker-2, started daemon)> 17
<ForkProcess(ForkPoolWorker-1, started daemon)> 19
EXCEPTION
我不明白为什么这些进程会被杀死,尤其是在函数中的 print 语句之后甚至没有抛出异常时。我真的不明白为什么只有当池中的进程数等于或小于机器上的内核数时才会发生这种情况。
【问题讨论】:
-
如果您正在运行 Windows,请首先使用
if __name__ == '__main__':保护您的代码 -
注意:它们不是线程,它们是进程。
-
这是在centos7上运行的。我没有在原始代码的底部包含保护性if语句,但刚才再次测试它是相同的行为。
-
您可以将
raise Exception更改为raise Exception(str(num))以确定哪个进程引发了错误。无论如何,这显然是一个竞争条件
标签: python python-3.x multiprocessing