我有一个生产者和消费者进程,以及它们之间的共享内存区域。当新数据可用时,我使用Condition对象从生产者进程发出消费者进程的信号。
当前问题是cond.wait()上的ArrayConsumer死锁,带有以下跟踪:
Producer: (3, 3, 30, 100)
Producer Done
Consumer: (3, 3, 30, 100)
Consumer Waiting...
根据我的理解,生产者在消费者准备好接收通知之前通知消费者,因此一直等待生产者的通知。确保消费者只有在准备好时才会发出信号的最佳方法是什么?
def ArrayConsumer(aArray, cond):
print('Consumer:', aArray.shape)
with cond:
print('Consumer Waiting...')
cond.wait()
print('Waiting finished..')
print('Consumer:', aArray[1, 1, 1, 1])
def ArrayProducer(aArray, cond):
print('Producer:', aArray.shape)
with cond:
aArray.fill(1)
cond.notify()
print('Producer Done')
if __name__ == '__main__':
# sharing numpy arrays
csi = csiMatrix(3, 3, 30, 100)
shared = sm.sharedmem.empty(csi.shape, dtype=complex)
shared[:] = csi
cond = Condition()
p = Process(target=ArrayProducer, args=(shared, cond,))
c = Process(target=ArrayConsumer, args=(shared, cond,))
p.start()
c.start()
p.join()
c.join()
答案 0 :(得分:1)
如果没有人在等待,Condition.notify
方法是noop。您需要在while循环中封装逻辑,并定期检查数据是否准备就绪。 Python文档有一个P&C example。您需要为wait
方法设置超时,并在每次迭代时检查数组中的数据。
使用Lock
和Event
会更容易避免使用长轮询机制。
def ArrayConsumer(aArray, lock, event):
print('Consumer:', aArray.shape)
print('Consumer Waiting...')
event.wait()
print('Waiting finished..')
with lock:
print('Consumer:', aArray[1, 1, 1, 1])
event.clear()
def ArrayProducer(aArray, lock, event):
print('Producer:', aArray.shape)
with lock:
aArray.fill(1)
event.set()
print('Producer Done')`
尽管如此,我强烈建议使用Pipe
或Queue
来实现生产者和消费者模式。这是一个更强大的机制。