Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理—池中的进程数是否会因出错而减少?_Python_Python 3.x_Parallel Processing_Multiprocessing_Python Multiprocessing - Fatal编程技术网

Python多处理—池中的进程数是否会因出错而减少?

Python多处理—池中的进程数是否会因出错而减少?,python,python-3.x,parallel-processing,multiprocessing,python-multiprocessing,Python,Python 3.x,Parallel Processing,Multiprocessing,Python Multiprocessing,守则: 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

守则:

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
而从5和以上,它打印所有范围1-19。那么这里发生了什么?进程是否在多次失败后崩溃

这当然是一个玩具示例,但它来自于我遇到的一个真实的代码问题——让多处理池稳定运行了几天之后,cpu使用率下降,就好像某些进程被终止一样(请注意,在03/04和03/06,当仍有大量任务要运行时,cpu使用率下降):


当代码终止时,它向我展示了一个(这里只有一个,而进程更多)
multiprocessing.pool.RemoteTraceback
-额外的问题是,这个回溯是随机的吗?在这个玩具示例中,它通常是
ValueError:1
,但有时也会出现其他数字。多处理是否会保留第一个崩溃进程的第一个回溯?

在一个窗口中使用
观察ps aux
,在另一个窗口中使用您的代码的快速实验似乎表明,不,异常不会使子进程崩溃

映射/星图操作的基础对象仅收集第一个异常,如果任何作业因异常而失败,则将整个映射作业视为失败

(发送给每个工作人员的作业数量取决于
chunksize
参数至
.map()
和friends。)

如果您想要更能适应异常,可以使用
。apply_async()

导入多处理
导入操作系统
def_过程(m):
如果m%2==0:
raise VALUE ERROR('我只处理奇数')
返回m*8
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
参数列表=列表(范围(1,20))
使用多处理池(2)作为p:
params_和_jobs=[((arg,),p.apply_async(_进程,(arg,))for args_列表中的arg]
对于参数,参数和作业中的作业:
job.等等
#通常您会使用'job.get()`,但它会引起异常,
#这不适用于本例,因此我们深入研究,仅使用
#它将返回或提升的“.\u”值:
打印(参数、类型(作业值)、作业值)
输出

(1,) <class 'int'> 8
(2,) <class 'ValueError'> I only work on odd numbers
(3,) <class 'int'> 24
(4,) <class 'ValueError'> I only work on odd numbers
(5,) <class 'int'> 40
(6,) <class 'ValueError'> I only work on odd numbers
(7,) <class 'int'> 56
(8,) <class 'ValueError'> I only work on odd numbers
(9,) <class 'int'> 72
(10,) <class 'ValueError'> I only work on odd numbers
(11,) <class 'int'> 88
(12,) <class 'ValueError'> I only work on odd numbers
(13,) <class 'int'> 104
(14,) <class 'ValueError'> I only work on odd numbers
(15,) <class 'int'> 120
(16,) <class 'ValueError'> I only work on odd numbers
(17,) <class 'int'> 136
(18,) <class 'ValueError'> I only work on odd numbers
(19,) <class 'int'> 152
(1,)8
我只处理奇数
(3,)  24
我只处理奇数
(5,)  40
我只处理奇数
(7,)  56
我只处理奇数
(9,)  72
我只处理奇数
(11,)  88
我只处理奇数
(13,)  104
我只处理奇数
(15,)  120
我只处理奇数
(17,)  136
我只处理奇数
(19,)  152

不,只是整个任务发生故障,而不是流程本身。您在玩具示例中观察到的行为可以用工作人员数量和iterable长度的组合得到的块大小来解释。从中获取函数
calc\u chunksize\u info
时,可以看到结果chunksize的差异:

calc_chunksize_info(n_workers=2, len_iterable=20)
# Chunkinfo(n_workers=2, len_iterable=20, n_chunks=7, chunksize=3, last_chunk=2)

calc_chunksize_info(n_workers=5, len_iterable=20)
# Chunkinfo(n_workers=5, len_iterable=20, n_chunks=20, chunksize=1, last_chunk=1) 
如果chunksize大于1,则当第一个taskel引发异常时,任务中所有未触及的内容也将丢失。直接在目标函数中处理可预期的异常,或者编写一个额外的错误处理包装来防止这种情况

当代码终止时,它向我展示了一个(这里只有一个,而进程要多得多)multiprocessing.pool.RemoteTraceback-这个回溯是随机的吗?在这个玩具示例中,它通常是ValueError:1,但有时也会出现其他数字。多处理是否保留了第一个崩溃进程的第一个回溯


工作进程从共享队列获取任务。从队列中读取是顺序的,因此任务1总是在任务2之前读取。然而,无法预测结果将以何种顺序在工人中准备好。有很多硬件和操作系统相关的因素在起作用,因此是的,回溯是随机的,因为结果的顺序是随机的,因为(字符串化)回溯是发送回父级的结果的一部分。结果还通过共享队列发送回,并且池内部处理JIT返回的任务。如果任务返回失败,则整个作业将标记为未成功,并放弃进一步到达的任务。一旦作业中的所有任务都返回,只有第一个检索到的异常才会在父级中重新检索

谢谢!仍然不完全清楚为什么它不能为所有进程打印-这是主要的谜团(cpu利用率下降,请参阅有问题的补充图片)。如果所有进程都启动了,人们会期望有一个稳定的cpu使用率-也许这个玩具示例并不完全符合这种情况,但是一些打印被用于较少进程的事实可能会给出一个提示
async
仍然让我无法理解。我会更彻底地了解这只是猜测,但当映射“预定”失败时,其他进程可能不会收到新的任务块,因此它们仍然处于空闲状态?我接受了@Darkonaut answer,因为它更接近地回答了问题,但将使用您的异步模式-谢谢!
calc_chunksize_info(n_workers=2, len_iterable=20)
# Chunkinfo(n_workers=2, len_iterable=20, n_chunks=7, chunksize=3, last_chunk=2)

calc_chunksize_info(n_workers=5, len_iterable=20)
# Chunkinfo(n_workers=5, len_iterable=20, n_chunks=20, chunksize=1, last_chunk=1)