簡體   English   中英

Python消費者生產者。 生產者等待消費者消費

[英]Python Consumer-Producer. Producer waits for the consumer to consume

我要完成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()

您的代碼中有一場競賽。

您的生產者fpga ,需要執行以下操作:

  1. acquire condition
  2. 使一些新數據可用(不清楚示例代碼中的情況)
  3. notify另一個線程
  4. release condition

消費者bbb需要執行以下操作:

  1. acquire condition
  2. wait收到數據可用的通知(重要:這將釋放鎖)
  3. 處理數據
  4. notify生產者已完成處理
  5. 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)

致電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 ,這將使消費者獲勝。 沒有睡眠或睡眠時間很短,制片人就可以獲勝。

解決方法只是在生產者中刪除對self.condition.wait()的調用。

兩個線程都可能wait另一個,例如以下時間表

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

是可能的,並很快導致死鎖。

您的方法不起作用,因為沒有“記住” notify ,如果在執行notify時沒有等待線程,則該通知會丟失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM