Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.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 多处理池.apply执行n-1次_Python_Python 3.x_Multiprocessing_Pool - Fatal编程技术网

Python 多处理池.apply执行n-1次

Python 多处理池.apply执行n-1次,python,python-3.x,multiprocessing,pool,Python,Python 3.x,Multiprocessing,Pool,我对多处理.Pool.apply有问题 我的目标是有5个进程,每个进程用100个元素填充一个数组(本测试用100个元素),然后将数组合并成一个长度为500的数组。问题是,不管出于什么原因,它最终只有400个元素,我都无法理解 我尝试过更改池创建的进程数量,但除了执行时间之外,这一点都没有改变 import torch.multiprocessing as mp import itertools pool = mp.Pool(processes=5) split = int(500/5) lst

我对
多处理.Pool.apply有问题

我的目标是有5个进程,每个进程用100个元素填充一个数组(本测试用100个元素),然后将数组合并成一个长度为500的数组。问题是,不管出于什么原因,它最终只有400个元素,我都无法理解

我尝试过更改池创建的进程数量,但除了执行时间之外,这一点都没有改变

import torch.multiprocessing as mp
import itertools

pool = mp.Pool(processes=5)
split = int(500/5)
lst =  pool.apply(RampedGraph, (split,[]))    #each foo returns a list of 100 elements
lst = list(itertools.chain.from_iterable(lst)) #merging the lists into one

len(lst)
>>>400
len(lst)
的预期输出应为
500

有人能告诉我我做错了什么吗

编辑Foo方法说明:

def RampedGraph(popsize, graph_lst):
    cyclic_size = int(math.ceil(popsize/2))
    acyclic_size = popsize - full_size
    append = graph_lst.append
    for _ in range(cyclic_size):
        t = c.Node().cyclic()
        nn = c.number_of_nodes()
        c = c.calculate(0, False)
        append((t,nn,c))
    for _ in range(acyclic_size):
        t = c.Node().acyclic()
        nn = c.number_of_nodes()
        c = c.calculate(0, False)
        append((t,nn,c))
    return graph_lst
将5个任务发送到任务池。 它导致同时调用
RampedGraph(split,[])
RampedGraph
返回的5个结果被收集到一个列表中,
lst

请注意,同时调用
RampedGraph
5次并不保证使用所有5个处理器。例如,如果
RampedGraph
完成得非常快,则一个处理器可能处理多个任务,而另一个处理器可能根本就不会被使用。 但是,如果
RampedGraph
花费了大量时间,通常您可以期望使用所有5个工作进程

注意:我使用
import multiprocessing as mp
运行上述代码,而不是
import torch.multiprocessing as mp
。但既然
torch.multi-processing
被认为是
multi-processing
的替代品,那就没什么区别了


使用
多处理
既有成本,也有好处。 当然,好处是能够同时使用多个处理器。 成本包括启动额外进程所需的时间,以及进程间通信的成本<代码>多处理
使用
队列
将参数传输到工作进程运行的函数,并将返回值传输回主进程。为了通过队列传输返回的值,通过pickle将对象序列化为字节。如果通过队列发送的pickle对象很大,则在使用多处理时会增加大量开销。请注意,所有这些成本都不是由相同代码的等效顺序版本引起的

特别是当辅助进程运行的函数很快完成时,开销成本可能会支配程序的总运行时间,使使用多处理的代码比相同代码的顺序版本慢


因此,在使用多处理时,提高速度的一个关键是尽量减少进程间通信,并确保工作进程做大量工作,这样开销成本就只占总运行时间的一小部分。

@unutbu done,添加了完整的方法
pool.apply(RampedGraph,(split,[])
仅调用
RampedGraph(拆分,[])
一次。你想调用
RampedGraph
五次吗?都使用相同的参数?@unutbu我试图为每个进程调用一次,这样我就可以合并5个包含100个元素的数组。都使用相同的参数。非常感谢!哼。你知道为什么这种方法比简单地用500个e填充数组要多花3倍的时间来执行吗元素?我认为它会缩短执行时间,而不是将执行时间增加三倍:/我补充了几句话,解释了为什么
多处理
有时会比同一代码的顺序版本慢。我不知道它是否适用于您的情况。我们可能需要查看您的实际可运行代码才能进行调查。
import torch.multiprocessing as mp
# import multiprocessing as mp
import itertools

def RampedGraph(popsize, graph_lst):
    print(mp.current_process().name)
    return list(range(100))

num_workers = 5
pool = mp.Pool(processes=num_workers)
split = int(500/num_workers)
lst =  pool.starmap(RampedGraph, [(split,[])]*num_workers)
lst = list(itertools.chain.from_iterable(lst)) 
print(len(lst))
# 500