Python:函数外部的列表的多处理追加



我正在尝试编写一个函数,该函数将附加到python中自身之外的列表中。用for循环测试,没有问题。然而,当我试图让它以多处理方式运行时,它就不再工作了。我创建了一个简单得多的代码来演示故障排除的问题:

from multiprocessing import Pool
items = []
def myFunc(a,b):
data = (a,b)
items.append(data)

if __name__ == '__main__':
with Pool(2) as p:
p.starmap(myFunc,[(0,1),(2,3)])
print(items)

应该带着回来

[(0,1),(2,3)]

与for循环一样,列表是空的,有指针吗?

一种方法是使用由SyncManager实例获得的list,该实例通过调用multiprocessing.Manager()并将其作为参数传递给myfunc:而获得

from multiprocessing import Pool, Manager
import functools
def myFunc(items, a, b):
data = (a,b)
items.append(data)

if __name__ == '__main__':
manager = Manager()
items = manager.list()
with Pool(2) as p:
p.starmap(functools.partial(myFunc, items),[(0,1),(2,3)])
print(items)

打印:

[(2, 3), (0, 1)]

另一种更接近您所拥有的方法是,使用这个特殊的可共享进程间list初始化池中的每个进程,而不必将其作为参数传递给您的工作人员:

from multiprocessing import Pool, Manager
def init_processes(l):
global items
items = l

def myFunc(a, b):
data = (a,b)
items.append(data)

if __name__ == '__main__':
manager = Manager()
items = manager.list()
with Pool(2, initializer=init_processes, initargs=(items,)) as p:
p.starmap(myFunc, [(0,1),(2,3)])
print(items)

打印:

[(0, 1), (2, 3)]

因此,每个作业提交一次(即,对starmap的调用中的每个参数传递一次(,而对池中的每个进程传递一次列表,就成了一个问题在你的情况下,我认为在成本方面几乎是一样的,但通常第二种方法会更好。

您会注意到,根据哪个调用首先完成,元组的添加顺序是不确定的。然而,调用的返回值将严格按照调用的顺序排列:

from multiprocessing import Pool, Manager
import functools
def myFunc(items, a, b):
data = (a,b)
items.append(data)
return data # let's also return the tuple

if __name__ == '__main__':
manager = Manager()
items = manager.list()
with Pool(2) as p:
results = list(p.starmap(functools.partial(myFunc, items),[(0,1),(2,3)]))
print(items)
print(results)

打印:

[(2, 3), (0, 1)]
[(0, 1), (2, 3)]

我不得不运行以上几次,以使得到的items数组为[(2, 3), (0, 1)]而不是[(0, 1), (2, 3)],但您仍然可以看到,从对myFunc的调用返回的值对应于";乔布斯;已提交。

您可以在数据被处理后返回数据,然后将其添加到项目列表中。

from multiprocessing import Pool

items = []
def myFunc(a,b):
data = (a,b)
# manipulate data...
return data

if __name__ == '__main__':
with Pool(2) as p:
items += p.starmap(myFunc,[(0,1),(2,3)])

print(items)

输出:

[(0, 1), (2, 3)]

多处理意味着代码在另一个进程中运行。甚至在另一个Python运行库中也是如此。

调用机制串行化您的列表,并以无缝的方式在另一个进程中对其进行反串行化,但它在另一端是一个200%独立和独立的对象(100%表示不在同一列表中,+100%表示在另一进程中:-(

该语言提供的更接近列表的是multiprocessing.Queue类,这是一个类似序列的对象,以透明的方式操作进程间通信部分

虽然您可以使用concurrent.futures轻松地从进程外工作者函数中获取返回值,这可能会导致更容易理解的代码库,但这将与您认为使用";列表";。(尽管我推荐它(

相关内容

  • 没有找到相关文章

最新更新