Python 多处理池意外终止线程

Python 多处理池意外终止线程,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,下面我用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,

下面我用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()
带有
池的输出=多处理。池(5)

1
2.
3.
4.
5.
6.
7.
8.
9
10
11
12
13
14
15
16
17
18
19
例外情况
但是,如果我将池的进程计数更改为等于或小于计算机上的内核数,则对
f()
的每次调用(其中
num
为)都不会打印

带有
池的输出=多处理。池(4)

1
3.
5.
7.
9
11
13
15
17
19
例外情况

我不明白为什么要终止这些进程,尤其是在函数中的print语句之后才抛出异常的情况下。我真的不明白为什么只有当池中的进程计数等于或小于机器上的内核数时才会发生这种情况。

参考 您可以看到一个可选参数
chunksize
,如果将其指定为1,即
pool.map(f,range(1,20),1)
,那么您将得到预期的结果

如果增加块大小(=例如6),您可能会看到:

<SpawnProcess(SpawnPoolWorker-1, started daemon)> 1
<SpawnProcess(SpawnPoolWorker-4, started daemon)> 7
<SpawnProcess(SpawnPoolWorker-3, started daemon)> 13
<SpawnProcess(SpawnPoolWorker-2, started daemon)> 19
1
7.
13
19
这表明任务的
chunksize
数量分配给池中的单个线程,当您在每个线程期间引发异常时,当然不会执行剩余chuck中的任务


从这里您可以知道
chunksize
的默认值是2。在您的例子中,存在这样一个变量的原因很容易看出,就是为了减少需要初始化的新线程的数量(当您有合适的chunksize时,这可能会节省资源和处理时间).

如果您运行的是windows,请首先使用
如果_uname__=='_u main__':
注意:它们不是线程,而是进程。这是在centos7上运行的。我没有在原始代码的底部包含保护性的if语句,但刚刚再次测试了它,结果是相同的。您可以将
raiseexception
更改为
raiseexception(str(num))
,以确定哪个进程引发了错误。不管怎样,这显然是一个与种族有关的问题:回答得好。要详细说明一点,调用
.map()
会生成带有
.submit()
的任务,但它不会将它们连接起来(除非您将
用作上下文管理器-那么连接将在
退出时发生)。因此,异常确实会发生,但不会“显示”,因为
.map()
返回未来对象的迭代器。此外,正如您所指出的,在这种特定情况下,chunksize为2,并且会找到相应的计算,并给出一些解释