如何在递归多处理函数中处理最大进程数的操作系统限制?

问题描述:

我有了解的一些问题我在下面的代码我写的其他一些剧本我写去认真处理多的简化回事过程:如何在递归多处理函数中处理最大进程数的操作系统限制?

import multiprocessing 
import time 
from random import randint 
from os import getpid 



def f(i, process_id, parent_process_message_queue): 

    print (i,process_id, getpid()) 
    time.sleep(randint(0,10)/100) 

    child_processes = [] 
    child_process_message_queue = multiprocessing.Queue() 

    if randint(0,10) > 4: 
     child_processes.append(multiprocessing.Process(target = f, args = (i+1, 0, child_process_message_queue))) 
     child_processes[-1].start() 
     child_processes.append(multiprocessing.Process(target = f, args = (i+1, 1, child_process_message_queue))) 
     child_processes[-1].start() 

    while not child_process_message_queue.empty(): 
     child_id = child_process_message_queue.get() 
     child_processes[child_id].join() 
    parent_process_message_queue.put(process_id) 


child_process_message_queue = multiprocessing.Queue() 

p = multiprocessing.Process(target = f, args = (0, 0, child_process_message_queue)) 
p.start() 

while not child_process_message_queue.empty(): 
    child_id = child_process_message_queue.get() 
    child_processes[child_id].join() 

p.join() 

当没有太多的递归调用发生(因为随机元素),那么这段代码似乎按预期工作。一个成功运行的

输出看起来是这样的:

0 0 57756 
1 0 57757 
1 1 57758 
2 0 57759 
2 1 57760 
3 0 57761 
3 1 57762 
3 0 57763 
3 1 57764 
4 0 57765 
4 1 57766 
4 0 57767 
4 1 57768 
5 0 57769 
5 1 57770 

然而,当正在犯了太多的递归调用,事情变得陌生;这样的事情出现,其中包括一些错误消息:

Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:1:1:1:2:2:1:1:1:1:2:1:2:1: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:2:2:1:2:2:2:1:1:2:2:2:1:1:1:1:2: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:2:2:2:2:2:2:2:2:2:2:1:2:2:2:1:2:2:2:1:2: 
Process Process-1:2:1:2:1:2:2:2:2:1:1:1:1:1:1:1:1:2:2:2:1:2:2:2:1:2:1:2:2:1:1:2:2:1:2:2:1:2:1:1:2:1:1: 
Process Process-1:2:1:2:2:2:2:1:2:2:2:1:1:1:2:1:2:2:1:2:2:1:1:2:1:1:1:2:1:1:2:2:1:1:1:1:1:1:1:1:2:1:1:2:2:2:2:2: 
Traceback (most recent call last): 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 249, in _bootstrap 
    self.run() 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 93, in run 
    self._target(*self._args, **self._kwargs) 
    File "queuetest2.py", line 18, in f 
    child_processes[-1].start() 
    File "/Users/user/anaconda/lib/python3.6/multiprocessing/process.py", line 105, in start 
[...] 
    Traceback (most recent call last): 
    BlockingIOError: [Errno 35] Resource temporarily unavailable 

我中搜索的结果错误(BlockingIOError:[错误35]),显然此行为是由所述凭证试图创建多个进程大于允许由OS引起的。现在我想知道:处理这个问题的最佳方法是什么?我不认为使用多处理的递归函数本身是一个坏主意,是吗?解决方案可能需要检查是否已达到流程上限,如果是这样,则继续在同一线程中递归,如果不是,则继续产生新流程,但这是否是一种合理的方法?

即使递归调用的次数很少,您的方法对性能也是非常不利的。

通常,在CPU绑定类型的作业上,最好保持过程/ CPU比率为1.对于IO界限而言,线程是更好的方法。对于混合作业,它会变得更加复杂一些,只有测试工作量才能给出具体的答案。

独立于工作负载,开发人员总是希望控制应用程序要创建的进程/线程的数量。为了达到这个目的,最简单的设计模式是使用Pool of Workers

Python库提供了两种不同的实现:multiprocessing.Poolconcurrent.futures.Executor