天天看點

python之生産者消費者模型python之生産者消費者模型

python之生産者消費者模型

生産者消費者模型作用于:

1.爬蟲的時候

2.分布式操作:celery

其本質:就是讓生産資料和消費資料的效率達到平衡并且最大化的效率

為什麼要使用生産者消費者模型?

在并發程式設計中,如果生産者處理速度很快,而消費者處理速度比較慢,那麼生産者就必須等待消費者處理完,才能繼續生産資料。同樣的道理,如果消費者的處理能力大于生産者,那麼消費者就必須等待生産者。為了解決這個等待的問題,就引入了生産者與消費者模型。讓它們之間可以不停的生産和消費。

什麼時候用這個模型?

程式中出現明顯的兩類任務,一類任務是負責生産,另外一類任務是負責處理生産的資料的(如爬蟲)

用該模型的好處?

1、實作了生産者與消費者的解耦和

2、平衡了生産力與消費力,就是生産者一直不停的生産,消費者可以不停的消費,因為二者不再是直接溝通的,而是跟隊列溝通的。

from multiprocessing import Queue
from multiprocessing import Process
import time
import random

def consumer(q,name):  # 消費者:通常取到某些資料之後還要進行某些操作
    while True:
        food = q.get()
        if food:
            print("%s吃了%s" % (name, food))
        else:
           break

def producer(q,name,food):  # 生産者:通常在資料之前需要通過某些代碼來擷取資料
    for i in range(10):
        foodi = "%s%s" % (food,i)
        print("%s生産了%s" % (name,foodi))
        # time.sleep(random.randint(1,3))
        q.put(foodi)
    #q.put(None)


if __name__ == "__main__":
    q = Queue()
    p1 = Process(target=producer,args=(q,'大壯','淚水'))
    c1 = Process(target=consumer,args=(q,'alex'))
    c1.start()
    p1.start()
    p1.join()

大壯生産了淚水0
大壯生産了淚水1
大壯生産了淚水2
大壯生産了淚水3
alex吃了淚水0
alex吃了淚水1
alex吃了淚水2
大壯生産了淚水4
大壯生産了淚水5
alex吃了淚水3
alex吃了淚水4
大壯生産了淚水6
alex吃了淚水5
大壯生産了淚水7
大壯生産了淚水8
大壯生産了淚水9
alex吃了淚水6
alex吃了淚水7
alex吃了淚水8
alex吃了淚水9

           

現在确實讓生産者不停的生産,消費者不斷的消費。但此時有一個問題就是主程序沒有結束。原因是:生産者p1生産完後就結束了,但是消費者c1,在q.get()取空之後,就一直在原地等待。解決這個問題無非就讓生産者在生産完畢後,就再往隊列中發送一個結束信号,這樣消費者接收到結束信号後就可以跳出死循環。修改如下:

from multiprocessing import Queue
from multiprocessing import Process
import time
import random

def consumer(q,name):  # 消費者:通常取到某些資料之後還要進行某些操作
    while True:
        food = q.get()
        if food:
            print("%s吃了%s" % (name, food))
        else:
           break

def producer(q,name,food):  # 生産者:通常在資料之前需要通過某些代碼來擷取資料
    for i in range(10):
        foodi = "%s%s" % (food,i)
        print("%s生産了%s" % (name,foodi))
        # time.sleep(random.randint(1,3))
        q.put(foodi)
    q.put(None)  #修改了這裡


if __name__ == "__main__":
    q = Queue()
    p1 = Process(target=producer,args=(q,'大壯','淚水'))
    c1 = Process(target=consumer,args=(q,'alex'))
    c1.start()
    p1.start()
    p1.join()