python多線程----生產者消費者模式

Lock版本:

#其實生產者和消費者都是要修改公共資源的
#但是消費者,要在生產者修改過公共資源後,才能處理公共資源,
#生產者生產後,就等着消費者處理完,生產者再修改數據.

import threading
import random
import time


gMoney=0
gLock=threading.Lock()

def producer():
    global gMoney
    while True:
        money=random.randint(100,1000)
        gLock.acquire()
        gMoney+=money
        print("%s生產了%d,現在共有%d元錢"%(threading.current_thread(),money,gMoney))
        gLock.release()
        time.sleep(2)

def consumer():
    global gMoney
    while True:
        money=random.randint(100,1000)
        gLock.acquire()
        if money<gMoney:
            gMoney-=money
            print("%s消費了%d,剩下%d元錢" % (threading.current_thread(), money, gMoney))
        gLock.release()
        time.sleep(1)

def main():
    for i in range(5):
        t=threading.Thread(target=producer)
        t.start()

    for x in range(5):
        t=threading.Thread(target=consumer)
        t.start()

if __name__ == '__main__':
    main()

Condition版本:

#Lock版本中上鎖,放鎖比較費時間
#在本版本種中如果不滿足生產條件,處於阻塞狀態
#wait:將當前線程處於阻塞狀態,並且釋放鎖
#notify:默認喚醒第一個正在等待的線程,不會立刻釋放鎖
#notify_all:喚醒所有等待的線程,不會釋放鎖,和notify都要放在releas函數前面
'''關於等待喚醒機制,可以理解爲線程可以執行有兩個條件:
有爭取執行權的資格 and 爭取到執行權,'
一個沒有爭取執行權資格的線程 不能 爭取執行權.
wait就是讓本線程放棄爭取的資格,如果有鎖就釋放掉,
notify就是重新給該線程爭取的資格'''



import threading
import random
import time


gMoney=0
gCondition=threading.Condition()

def producer():
    global gMoney
    while True:
        money=random.randint(100,1000)
        gCondition.acquire()
        gMoney+=money
        print("%s生產了%d,現在共有%d元錢"%(threading.current_thread(),money,gMoney))
        gCondition.notify_all()
        gCondition.release()
        time.sleep(2)

def consumer():
    global gMoney
    while True:
        money=random.randint(100,1000)
        gCondition.acquire()
        while money>gMoney:
            gCondition.wait()
        gMoney-=money
        print("%s消費了%d,剩下%d元錢" % (threading.current_thread(), money, gMoney))
        gCondition.release()
        time.sleep(1)

def main():
    for i in range(5):
        t=threading.Thread(target=producer)
        t.start()

    for x in range(5):
        t=threading.Thread(target=consumer)
        t.start()

if __name__ == '__main__':
    main()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章