Python ConsumerProducer。生产者等待消费者消费

2024-04-20 05:58:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我想有两个任务。一个是生产者,另一个是消费者。为了生成新的数据,生产者必须等待消费者消费数据。执行流程必须是: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()

Tags: nameselfdatainitdefconditionthread生产者
2条回答

你的代码里有一场比赛。在

您的制作人fpga需要执行以下操作:

  1. acquirecondition
  2. 提供一些新数据(不清楚在示例代码中是如何发生的)
  3. notify另一个线程
  4. releasecondition

消费者bbb需要执行以下操作:

  1. acquirecondition
  2. wait得到数据可用的通知(重要:这将释放锁)
  3. 处理数据
  4. notify完成处理的生产商
  5. releasecondition

您的消费者正在执行上述步骤:

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

但是,您的制作人没有遵循以下步骤:

^{pr2}$

您在调用notify后立即有一个不必要的wait调用。这将引入竞争条件。你可以这样结束:

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,这将让消费者获胜。如果没有睡眠,或者睡眠时间很短,制作人就可以获胜。在

修复方法只是删除在producer中对self.condition.wait()的调用。在

可能两个线程wait为另一个线程,例如下面的调度

fpga.acquire
fpga.notify
fpga.wait
bbb.acquire
bbb.wait

很快就会导致死锁。在

您的方法无法工作,因为notify没有“记住”,如果在执行notify时没有等待线程,则通知将丢失。在

相关问题 更多 >