код:
import multiprocessing
print(f'num cpus {multiprocessing.cpu_count():d}')
import sys; print(f'Python {sys.version} on {sys.platform}')
def _process(m):
print(m) #; return m
raise ValueError(m)
args_list = [[i] for i in range(1, 20)]
if __name__ == '__main__':
with multiprocessing.Pool(2) as p:
print([r for r in p.starmap(_process, args_list)])
печать:
num cpus 8
Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 03:13:28)
[Clang 6.0 (clang-600.0.57)] on darwin
1
7
4
10
13
16
19
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 121, in worker
result = (True, func(*args, **kwds))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 47, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "/Users/ubik-mac13/Library/Preferences/PyCharm2018.3/scratches/multiprocess_error.py", line 8, in _process
raise ValueError(m)
ValueError: 1
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/ubik-mac13/Library/Preferences/PyCharm2018.3/scratches/multiprocess_error.py", line 18, in <module>
print([r for r in p.starmap(_process, args_list)])
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 298, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 683, in get
raise self._value
ValueError: 1
Process finished with exit code 1
При увеличении числа процессов в пуле до 3 или 4 выводятся все нечетные числа (возможно, не по порядку):
1
3
5
9
11
7
13
15
17
19
в то время как от 5 и выше он печатает весь диапазон 1-19. Так что здесь происходит? Сбои процессов после ряда сбоев?
Это, конечно, игрушечный пример, но он связан с реальной проблемой, с которой я столкнулся - из-за того, что многопроцессорный пул оставался на несколько дней стабильно, загрузка процессора снижалась, как будто некоторые процессы были убиты (обратите внимание, что загрузка процессора идет вниз 03/04 и 03/06, когда еще предстояло выполнить много заданий):
Когда код завершился, он подарил мне одну (и только одну, как здесь, в то время как процессов было намного больше) multiprocessing.pool.RemoteTraceback
- бонусный вопрос - это случайная трассировка? В этом игрушечном примере это обычно ValueError: 1
, но иногда появляются и другие числа. Сохраняет ли многопроцессорность первую трассировку от первого сбойного процесса?