有没有类似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是一个占用大量内存的函数,其实例必须占用大量内存。
答案 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个流程。如果将进程值留为空白,则它将使用尽可能多的资源。
有帮助吗?