我想要完成2项任务。一个是生产者,另一个是消费者。生产者必须等待消费者使用数据才能生成新数据。执行流程必须是:fpga,bbb,fpga,bbb,fpga,bbb,fpga,bbb,fpga,bbb ..... 当我有一个很大的睡眠时间为生产者每个人工作正常,但当睡眠时间很短我有一个僵局。 ¿有谁知道为什么?我的代码:
class fpga (threading.Thread):
def __init__(self,condition,data):
threading.Thread.__init__(self)
self.name='fpga'
self.condition=condition
self.data=data
self.sleepTime=1.0/(300.0*18.0)
self.count=0
def run(self):
while True:
newData='YxxY'
self.condition.acquire()
self.condition.notify()
self.condition.wait()
self.condition.release()
time.sleep(self.sleepTime) #sleep some time
print 'fpga'
class bbb (threading.Thread):
def __init__(self,condition,data):
threading.Thread.__init__(self)
self.name='bbb'
self.condition=condition
self.data=data
def run (self):
while True:
self.condition.acquire()
self.condition.wait()
self.condition.notify()
self.condition.release()
print 'bbb'
if __name__=='__main__':
dataFpga=[]
dataFromFpgaCondition=threading.Condition()
threadfpga=fpga(dataFromFpgaCondition,dataFpga)
threadBbb=bbb(dataFromFpgaCondition,dataFpga)
threadBbb.start()
threadfpga.start()
threadBbb.join()
threadfpga.join()
答案 0 :(得分:3)
你的代码中有一场比赛。
您的制作人fpga
,需要执行以下操作:
acquire
condition
锁定notify
另一个帖子release
condition
锁定消费者bbb
需要执行以下操作:
acquire
condition
锁定wait
通知数据可用(重要:这会释放锁定)notify
已完成处理的制作人release
condition
锁定您的消费者正在完成上面列出的步骤:
self.condition.acquire() # Step 1
self.condition.wait() # Step 2
self.condition.notify() # Step 4 (step 3 is left out here, but its not important)
self.condition.release() # Step 5
但是,您的制作人没有遵循以下步骤:
self.condition.acquire() # Step 1
self.condition.notify() # Step 2
self.condition.wait() # This isn't a step! And we're releasing the lock when we do it!
self.condition.release() # Step 4 (no step 3 again, but that's ok)
在致电wait
后,您会立即拨打notify
电话。这引入了竞争条件。你最终可以得到这个:
bbb.condition.acquire()
bbb.condition.wait() # This releases the lock and then blocks, waiting to be notified
fpa.condition.acquire()
fpga.condition.notify()
fpga.condition.wait() # bbb acquires the lock right after this, because it's in wait()
bbb.condition.notify()
bbb.condition.release() # fpga.wait() now completes
fpga.condition.release() # Ok, both threads just called release. Now it's race.
fpga.condition.acquire() # The producer won the race. This is bad.
fpga.condition.notify()
fpga.condition.wait() # Releases the lock and waits
bbb.condition.acquire()
bbb.condition.wait() # No they're both waiting, and you're deadlocked.
你可以通过添加sleep
来避免这种情况,因为一旦我们到达比赛点,制作人就会暂停sleep
,这会让消费者获胜。如果没有睡眠,或者睡眠时间很短,生产者就可以获胜。
修复只是删除生产者对self.condition.wait()
的调用。
答案 1 :(得分:0)
两个线程wait
可能是另一个,例如以下时间表
fpga.acquire
fpga.notify
fpga.wait
bbb.acquire
bbb.wait
是可能的,并且很快就会导致死锁。
您的方法不起作用,因为notify
未被“记住”,如果执行notify
时没有等待线程,则通知将丢失。