プロデューサーの消費者モデル
固定モデルは、問題や日常を解決することです
メーカー:1で生成されたデータを参照します
消費者データ処理の一つを意味します
問題を解決するために使用したもの
- ケース
- ホテルのダイニングルームのプロデューサーであります
- 私たちは消費者です
シェフが一つだけの皿を想定し、その後、彼の料理に、我々は待つ必要がある、と私たちは食べる、と彼はまた、必要
両方の効率が矛盾するので非効率性、両側は、互いに待ちます
具体的な解決策:
- 最初の異なるタスクを担当する別のプロセスを可能にするために、両者の間のカップリングのロックを解除します
- 限り、双方がその上に容器を使用するように、共有容器、双方のバランスをとる能力を提供します。キューはプロセス間でメモリを共有することができますので、それはキューを推奨しました
例えば:
from multiprocessing import Process, Queue
import requests, re, time, random, os
def product(urls, q):
'''生产者,爬取数据'''
for ind, url in enumerate(urls):
response = requests.get(url)
response.encoding = response.apparent_encoding
q.put(response.text)
print(f'第{ind+1}个网站,爬取状态为{response.status_code},进程编号{os.getpid()}')
def customer(q):
'''消费者,处理数据'''
i = 0
while True:
text = q.get()
time.sleep(random.random())
res = re.findall('src=//(.*?) width', text)
i += 1
print("第%s个任务获取到%s个img%s个编码信息" % (i, len(res), len(text)))
if __name__ == '__main__':
urls = [
'http://www.baidu.com',
'http://www.jd.com',
'http://www.taobao.com',
]
q = Queue()
p = Process(target=product, args=(urls, q))
p.start()
c = Process(target=customer, args=(q,))
c.start()
第1个网站,爬取状态为200,进程编号1672
第1个任务获取到1个img2287个编码信息
第2个网站,爬取状态为200,进程编号1672
第2个任务获取到0个img90221个编码信息
第3个网站,爬取状态为200,进程编号1672
第3个任务获取到0个img141513个编码信息
...
停止するときには、問題を持っていない、消費者は知りません
もし唯一のプロデューサー、あなたはロゴの生産終了として、製造終了後のQなしにして置くことができますが、しかし、生産者はより多くの時間を持って、このアプローチは実行不可能
JoinableQueue
- キュー、一貫した使用から継承されます。
- 参加追加(待機)とtask_done(タスク完了)
うブロッキング機能はどこに参加ある要素にtask_done番号がコールの数に等しくなるまでブロックタスクキューの処理を表すためにリリースされる予定が完了し
ケース:
from multiprocessing import Process, JoinableQueue
import time, random
'''如何判定今天的热狗真的吃完了
1.确定生成者任务完成
2.确定生出来的数据已经全部处理完成'''
# 生产热狗
def product(q, name):
for i in range(3):
dog = f"{name}的热狗{i + 1}"
time.sleep(random.random())
print("生产了", dog)
q.put(dog)
# 吃热狗
def customer(q):
while True:
dog = q.get()
time.sleep(random.random())
print("消费了%s" % dog)
q.task_done() # 标记这个任务处理完成
if __name__ == '__main__':
# 创建一个双方能共享的容器
q = JoinableQueue()
# 生产者进程
p1 = Process(target=product, args=(q, "上海分店"))
p2 = Process(target=product, args=(q, "北京分店"))
p1.start()
p2.start()
# 消费者进程
c = Process(target=customer, args=(q,))
c.daemon = True # 将消费者设置为守护进程 当主进程确认 任务全部完成时 可以随着主进程一起结束
c.start()
p1.join()
p2.join() # 代码走到这里意味着生产方完成
q.join() # 意味着队列中的任务都处理完成了
# c.terminate() # 也可以直接终止消费者进程
(例えばRedisのメッセージキュー、MQメッセージキューなどの)様々なキューは、一般的な消費者の生産モデルです。
クリッピングは、主にトラフィックに使用され、サーバが高いため、並行性の崩壊しないことを保証