生産者 - 消費者モデル導入
なぜ生産者 - 消費者モデルを使用
生産者が生産データのタスクを指しプロデューサーはすぐに処理した場合に、消費者の処理速度が非常に遅いながら生産者は消費者が取り扱うようにするために待たなければならないので、消費者は、、並行プログラミングでは、データ処理のタスクを指し、生産データを継続するためには、終了しました。消費者の能力がプロデューサーよりも大きい場合には、同じトークンによって、消費者は生産者を待たなければならないでしょう。その生産者と消費者のパターンの導入をこの問題を解決するには。
生産者と消費者のモードとは何ですか
生産者 - 消費者モデルは、容器の生産者と消費者によって解決される強い結合の問題です。生産者と消費者が直接相互に通信していない、とキューを遮断することによって通信する、消費者を待たずに本番データの処理が完了した後にプロデューサーので、直接スローのブロッキングキューは、消費者がデータへのプロデューサーを見つけることができませんが、キューをブロックから直接採取し、キューが処理能力の生産者と消費者のバランスをとる、ブロッキングバッファーに相当します。
ブロッキングキューは、生産者と消費者を分離するために使用されます
二つの生産者 - 消費者モデルの実装
生産者 - 消費者モデルを実践するためにコホート研究部に基づき、
from multiprocessing import Process,Queue
import time,random,os
def consumer(q,name):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[43m%s 吃 %s\033[0m' %(name,res))
def producer(q,name,food):
for i in range(3):
time.sleep(random.randint(1,3))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m%s 生产了 %s\033[0m' %(name,res))
if __name__ == '__main__':
q=Queue()
#生产者们:即厨师们
p1=Process(target=producer,args=(q,'egon','包子'))
#消费者们:即吃货们
c1=Process(target=consumer,args=(q,'alex'))
#开始
p1.start()
c1.start()
print('主')
結果
主
egon 生产了 包子0
egon 生产了 包子1
alex 吃 包子0
alex 吃 包子1
egon 生产了 包子2
alex 吃 包子2
空のQをとった後のp、それが終了した後、生産の生産が、消費者Cは、(死のサイクルに残ったとq.getに従事していますので、この時点では、主な問題は、プロセスが終了したことがないということです)このステップ。
解決策が、信号の終わりは死のサイクルから抜け出すことができた後、消費者が受け取ったように、生産は、キューの最後に、完成した後、信号を送信した後、それが生産することができます
from multiprocessing import Process,Queue
import time,random,os
def consumer(q,name):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[43m%s 吃 %s\033[0m' %(name,res))
def producer(q,name,food):
for i in range(3):
time.sleep(random.randint(1,3))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m%s 生产了 %s\033[0m' %(name,res))
if __name__ == '__main__':
q=Queue()
#生产者们:即厨师们
p1=Process(target=producer,args=(q,'egon','包子'))
#消费者们:即吃货们
c1=Process(target=consumer,args=(q,'alex'))
#开始
p1.start()
c1.start()
p1.join()
q.put(None)
print('主')
しかし、いくつかの最終消費者は、上記の溶液、複数のプロデューサと複数のコンシューマがある場合、我々は非常に低い解決する方法が必要があるいくつかの信号送信する必要があります。例えば、かなり低いが、
from multiprocessing import Process,Queue
import time,random,os
def consumer(q,name):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[43m%s 吃 %s\033[0m' %(name,res))
def producer(q,name,food):
for i in range(3):
time.sleep(random.randint(1,3))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m%s 生产了 %s\033[0m' %(name,res))
if __name__ == '__main__':
q=Queue()
#生产者们:即厨师们
p1=Process(target=producer,args=(q,'egon1','包子'))
p2=Process(target=producer,args=(q,'egon2','骨头'))
p3=Process(target=producer,args=(q,'egon3','泔水'))
#消费者们:即吃货们
c1=Process(target=consumer,args=(q,'alex1'))
c2=Process(target=consumer,args=(q,'alex2'))
#开始
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
q.put(None)
q.put(None)
q.put(None)
print('主')
実際には、私たちの思考は、信号にそれの終わりを送信する以外の何ものでもありません、別のキューがあり、そのようなメカニズムを提供します
JoinableQueue([MAXSIZE])
这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。
パラメータ説明
maxsize是队列中允许最大项数,省略则无大小限制。
メソッドの紹介
JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
生産者 - 消費者モデルを達成JoinableQueue基づき、
from multiprocessing import Process,JoinableQueue
import time,random,os
def consumer(q,name):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[43m%s 吃 %s\033[0m' %(name,res))
q.task_done() #发送信号给q.join(),说明已经从队列中取走一个数据并处理完毕了
def producer(q,name,food):
for i in range(3):
time.sleep(random.randint(1,3))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m%s 生产了 %s\033[0m' %(name,res))
q.join() #等到消费者把自己放入队列中的所有的数据都取走之后,生产者才结束
if __name__ == '__main__':
q=JoinableQueue() #使用JoinableQueue()
#生产者们:即厨师们
p1=Process(target=producer,args=(q,'egon1','包子'))
p2=Process(target=producer,args=(q,'egon2','骨头'))
p3=Process(target=producer,args=(q,'egon3','泔水'))
#消费者们:即吃货们
c1=Process(target=consumer,args=(q,'alex1'))
c2=Process(target=consumer,args=(q,'alex2'))
c1.daemon=True
c2.daemon=True
#开始
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
#1、主进程等生产者p1、p2、p3结束
#2、而p1、p2、p3是在消费者把所有数据都取干净之后才会结束
#3、所以一旦p1、p2、p3结束了,证明消费者也没必要存在了,应该随着主进程一块死掉,因而需要将生产者们设置成守护进程
print('主')
三生産者 - 消費者モデルの概要
1、プログラムは、役割の2種類があります
一类负责生产数据(生产者)
一类负责处理数据(消费者)
2、問題を解決するための生産者 - 消費者モデルの導入であります
平衡生产者与消费者之间的速度差
程序解开耦合
3、どのように生産者 - 消費者モデルを達成するために
生产者<--->队列<--->消费者