问题描述
在下面的代码中,我期望print('q.count',q.count)
为2,因为count
是一次使用q = QueueFun()
初始化的变量,然后在read_queue
方法中递增,而不是{{1} }打印0。在多进程之间共享计数器的正确方法是什么?
完整代码:
print('q.count',q.count)
解决方法
与线程不同,不同的进程具有不同的地址
空格:它们彼此之间不共享内存。写作
在一个过程中将其更改为变量将不会更改(非共享)
另一个过程中的变量。
在原始示例中,最后的计数为0,因为
主要流程从未改变过(不管其他什么
产生的进程)。
使用Queue在进程之间进行通信可能更好。
如果确实需要,可以使用Value或Array:
17.2.1.5. Sharing state between processes
如上所述,在进行并行编程时,通常 最好尽量避免使用共享状态。这是 使用多个进程时尤其如此。
但是,如果您确实确实需要使用一些共享数据,则 多重处理提供了两种方法。
共享内存可以使用Value或数据存储在共享内存映射中 数组。
...
这些共享对象将是进程和线程安全的。
像+ =这样的涉及读写的操作不是原子操作。
问题代码的略微修改版本:
from multiprocessing import Process,Queue,Value
class QueueFun():
def __init__(self):
self.readCount = Value('i',0)
self.writeCount = Value('i',0)
def write_queue(self,work_tasks,MAX_SIZE):
with self.writeCount.get_lock():
if self.writeCount != MAX_SIZE:
self.writeCount.value += 1
work_tasks.put(1)
def read_queue(self,MAX_SIZE):
with self.readCount.get_lock():
if self.readCount.value != MAX_SIZE:
self.readCount.value += 1
work_tasks.get()
if __name__ == '__main__':
q = QueueFun()
MAX_SIZE = 2
work_tasks = Queue()
write_processes = []
for i in range(MAX_SIZE):
write_processes.append(Process(target=q.write_queue,args=(work_tasks,MAX_SIZE)))
for p in write_processes: p.start()
read_processes = []
for i in range(MAX_SIZE):
read_processes.append(Process(target=q.read_queue,MAX_SIZE)))
for p in read_processes: p.start()
for p in read_processes: p.join()
for p in write_processes: p.join()
print('q.writeCount.value',q.writeCount.value)
print('q.readCount.value',q.readCount.value)
注意:从多个过程打印到标准输出,
会导致输出混乱(不同步)。