使用共享内存进行多处理

时间:2016-08-20 14:16:40

标签: python arrays multiprocessing shared-memory

有人可以使用锁来使用python的多处理模块向我提供示例代码以在工作进程池或甚至单独生成的进程之间共享可写数组或列表吗?我的下面的代码产生了2个进程,其中一个应该打印'1'而另一个应该打印'2'到共享数组。但是,当我尝试在处理后打印出数组的元素时,它只给出了一个0的列表。我哪里错了?我希望在多个进程之间共享可写数据结构。

以下是我的代码:

import multiprocessing

arr=multiprocessing.Array('i',10,lock=True)
lock=multiprocessing.RLock()

def putitin(n):
    for i in range(5):
        lock.acquire()
        arr.append(n)
        lock.release()
    return

p1=multiprocessing.Process(target=putitin,args=(1,))
p2=multiprocessing.Process(target=putitin,args=(2,))

p1.start()
p2.start()

p1.join()
p2.join()

for i in range(10):
    print(arr[i])

2 个答案:

答案 0 :(得分:1)

您的代码的一个潜在问题是,要在Windows上使用multiprocessing,您需要将主进程的代码放在if __name__ == '__main__':块中。请参阅Windowsmultiprocessing Programming guidelines部分的安全导入主模块小节。

另一个主要问题是您正在尝试在流程中共享全局变量。因为每个子进程都在自己的非共享内存空间中运行,所以每个子进程都有自己的arr。 (但只是模块级常量的变量是可以的)

最后,multiprocessing.Array具有固定大小,并且没有您的代码尝试在extend()函数中使用的putitin()方法 - 因此您似乎也想要一个可写的可调整大小的容器(已订购,可能通过整数索引访问)。

在这种情况下,以下类似的东西可能是合适的。在更改对象之前,您不需要显式锁定对象,因为它是一个线程安全的共享对象。

import multiprocessing

def putitin(lst, value):
    for i in range(5):
        lst.append(value)

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    lst = manager.list()

    p1 = multiprocessing.Process(target=putitin, args=(lst, 1))
    p2 = multiprocessing.Process(target=putitin, args=(lst, 2))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    for i in range(len(lst)):
        print(lst[i])

输出:

1
1
1
1
1
2
2
2
2
2

答案 1 :(得分:0)

我在您的代码中发现的一些问题。首先,seems to be a good idea将所有共享资源传递给子级并使用<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <ul class="main"> <li><input type="checkbox" id="select_all" /> Select all</li> <ul> <li><input name="inv_ammount" type="checkbox" class="cbox" value="1"/>Item 1</li> <li><input name="inv_ammount" type="checkbox" class="cbox" value="2"/>Item 2</li> <li><input name="inv_ammount" type="checkbox" class="cbox" value="3"/>Item 3</li> <li><input name="inv_ammount" type="checkbox" class="cbox" value="4"/>Item 4</li> <li><input name="inv_ammount" type="checkbox" class="cbox" value="5"/>Item 5</li> Total Amount : <input id="Totalcost" /> </ul> </ul>。其次,我不认为if __name__ == '__main__'multiprocessing.Array方法(至少它对Python2和Python3不起作用)。第三,由于您使用的是append(),我认为您不需要额外的锁定。

如果你需要为数组附加值,我会使用单独的Counter变量(参见下面的代码)。

lock=True

话虽如此,你的高级目标是什么?你想用它做什么?也许可以使用import multiprocessing def putitin(n, arr, counter): for i in range(5): with counter.get_lock(): index = counter.value counter.value += 1 arr[index] = n if __name__ == '__main__': arr = multiprocessing.Array('i', 10,lock=True) counter = multiprocessing.Value('i', 0, lock=True) p1 = multiprocessing.Process(target=putitin,args=(1, arr, counter)) p2 = multiprocessing.Process(target=putitin,args=(2, arr, counter)) p1.start() p2.start() p2.join() p1.join() for i in range(10): print(arr[i])