day50-1生産者 - 消費者モデル

プロデューサーの消費者モデル

固定モデルは、問題や日常を解決することです

メーカー:1で生成されたデータを参照します

消費者データ処理の一つを意味します

問題を解決するために使用したもの

  • ケース
    • ホテルのダイニングルームのプロデューサーであります
    • 私たちは消費者です

シェフが一つだけの皿を想定し、その後、彼の料理に、我々は待つ必要がある、と私たちは食べる、と彼はまた、必要

両方の効率が矛盾するので非効率性、両側は、互いに待ちます

具体的な解決策:

  1. 最初の異なるタスクを担当する別のプロセスを可能にするために、両者の間のカップリングのロックを解除します
  2. 限り、双方がその上に容器を使用するように、共有容器、双方のバランスをとる能力を提供します。キューはプロセス間でメモリを共有することができますので、それはキューを推奨しました

例えば:

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メッセージキューなどの)様々なキューは、一般的な消費者の生産モデルです。

クリッピングは、主にトラフィックに使用され、サーバが高いため、並行性の崩壊しないことを保証

おすすめ

転載: www.cnblogs.com/lucky75/p/11134837.html