如何在Python中按顺序加载和执行进程?

时间:2019-01-05 09:36:21

标签: python parallel-processing multiprocessing

有没有类似map的方法不会立即将所有子进程加载到内存中,相反,如果总CPU线程数为四个,则首先加载四个进程并执行它,如果四个完成之一,它将执行加载另一个并替换它。

标准库中的pool.map一次加载所有作业,并以随机顺序执行它们。如果要执行大量作业,内存将溢出。

我已阅读official documentation of Python3,但尚未找到任何相关材料。

我需要的功能太详细了,我认为没有任何第三方库故意实现此功能。

我的期望:

有四个核心计算机。

y = XXX.map(f,range(1,100))

如果1〜4未完成,则系统内存中没有 f(5)。当这四个任务之一完成时,例如f(2),它将在f(2)的位置加载f(5)。

让我们谈谈功能“ f”的功能。 f是一个占用大量内存的函数,其实例必须占用大量内存。

2 个答案:

答案 0 :(得分:0)

首先,在内存中具有所有子进程的map的概念是不正确的,通过将map变成一个列表,map在内存中具有整个可迭代(输入)的对象。但是,它只有您创建的工作程序(池)数,请参见示例。

如果问题是可迭代项很长并且本身消耗大量内存,那么imap是一个更好的选择,因为它没有将整个可迭代项保留在内存中,它只需要将下一个迭代项交给工作人员即可。另外一个好处是,imap可以直接(但按顺序)返回结果,以便主进程可以使用它。

一个工人完成任务后,由于时间延迟,可以使用示例代码进行验证。

示例:

import multiprocessing
import random
import time

def func(x):
    """
    1. Prints the process and input
    2. Waits a bit
    3. Uses a lot of memory
    4. Waits a random amount more
    """
    print(f'{multiprocessing.current_process()}: {x}')
    time.sleep(5)
    a = list(range(10000000))
    time.sleep(5 + random.randint(0, 5))

if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=4)
    pool.map(func, range(10))

输出:

<ForkProcess(ForkPoolWorker-1, started daemon)>: 0
<ForkProcess(ForkPoolWorker-2, started daemon)>: 1
<ForkProcess(ForkPoolWorker-3, started daemon)>: 2
<ForkProcess(ForkPoolWorker-4, started daemon)>: 3
<ForkProcess(ForkPoolWorker-2, started daemon)>: 4
<ForkProcess(ForkPoolWorker-4, started daemon)>: 5
<ForkProcess(ForkPoolWorker-3, started daemon)>: 6
<ForkProcess(ForkPoolWorker-1, started daemon)>: 7
<ForkProcess(ForkPoolWorker-4, started daemon)>: 8
<ForkProcess(ForkPoolWorker-3, started daemon)>: 9

答案 1 :(得分:-1)

我是从Treddy的答案here借来的:

您只需要编辑池进程值。例如,像这样:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # start 4 worker processes
    result = pool.apply_async(f, [10])    # evaluate "f(10)" asynchronously
    print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
    print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"

在此示例中,有10个作业要完成,但是最多可以完成4个流程。如果将进程值留为空白,则它将使用尽可能多的资源。

有帮助吗?