我正在尝试第一次使用多重处理,并且遇到了一些相当基本的问题。我在下面有一个玩具示例,其中两个进程将数据添加到列表中:
def add_process(all_nums_class, numbers_to_add):
for number in numbers_to_add:
all_nums_class.all_nums_list.append(number)
class AllNumsClass:
def __init__(self):
self.all_nums_list = []
all_nums_class = AllNumsClass()
p1 = Process(target=add_process, args=(all_nums_class, [1,3,5]))
p1.start()
p2 = Process(target=add_process, args=(all_nums_class, [2,4,6]))
p2.start()
all_nums_class.all_nums_list
我希望这些进程之间共享all_nums_class,以便它们都可以添加到其all_nums_list中-因此结果应该是
[1,2,3,4,5,6]
而不是我现在得到的是好旧的
[]
有人可以建议吗?我在名称空间上玩了一点,但还没有在这里使用。
我觉得最好在Jupyter笔记本电脑上这样做(以防万一)。
答案 0 :(得分:4)
您可以使用多处理Queue or a Pipe在进程之间共享数据。队列既是线程安全的,又是进程安全的。使用管道时,您必须更加小心,因为如果两个进程(或线程)尝试同时从管道的同一端读取或写入管道,则管道中的数据可能会损坏。当然,同时使用管道的不同末端的过程不会造成损坏的风险。
当前,您的实现产生两个单独的进程,每个进程均具有自己的自己 self.all_nums_list
。因此,您实际上生成了AllNumsClass
的三个对象:一个在主程序中,一个在p1
中,一个在p2
中。由于进程是独立的,并且不共享相同的内存空间,因此它们可以正确地追加,但是对于每个进程,它们都可以追加到自己的self.all_nums_list
中。这就是为什么在主程序中打印all_nums_class.all_nums_list
时要打印主进程的self.all_nums_list
,这是一个空列表。要共享数据并使进程附加到同一列表,我建议使用队列。
使用队列和流程的示例
import multiprocessing as mp
def add_process(queue, numbers_to_add):
for number in numbers_to_add:
queue.put(number)
class AllNumsClass:
def __init__(self):
self.queue = mp.Queue()
def get_queue(self):
return self.queue
if __name__ == '__main__':
all_nums_class = AllNumsClass()
processes = []
p1 = mp.Process(target=add_process, args=(all_nums_class.get_queue(), [1,3,5]))
p2 = mp.Process(target=add_process, args=(all_nums_class.get_queue(), [2,4,6]))
processes.append(p1)
processes.append(p2)
for p in processes:
p.start()
for p in processes:
p.join()
output = []
while all_nums_class.get_queue().qsize() > 0:
output.append(all_nums_class.get_queue().get())
print(output)
此实现是异步,因为它没有按顺序应用。每次运行它,您可能会得到不同的输出。
示例输出
[1、2、3、5、4、6]
[1、3、5、2、4、6]
[2,4,6,1,1,3,5]
[2,1,4,3,5,6]
维护结果的有序列表或无序列表的更简单方法是使用mp.Pool类。具体来说,Pool.apply
和Pool.apply_async
函数。 Pool.apply
将锁定主程序,直到所有进程完成为止,如果我们要为特定应用程序以特定顺序获取结果,这将非常有用。相反,Pool.apply_async
将立即提交所有过程,并在完成后立即检索结果。另一个不同之处是,我们需要在get
调用之后使用Pool.apply_async
方法,以获取完成的过程的返回值。