114のPythonプログラム動作処理 - プロセス間通信(multiprocess.Queue)

部屋、プロセス間通信

IPC。複数のプロセス間では相互に通信します。プロセス間通信は、単一の言語だけの問題ではありません。代わりに、各言語がでています。達成するためのプロセス間通信がたくさんあります。C言語は、次のとおりパイプ:パイプ(匿名パイプ)、名前付きパイプ、信号、共有メモリ、メッセージキュー、セマフォ、等

Pythonは、ここでプロセス間通信キューを通じて達成され、

第二に、キュー

2.1概念--- multiprocessing.Queue

共有プロセスキューを作成、キューは、マルチプロセスセーフキューキューが複数のプロセス間でデータを渡すために使用することが可能です。

Queue([maxsize])共有プロセスキューを作成します。
パラメータ:MAXSIZEはキューに許可されるエントリの最大数です。省略した場合、サイズ制限なし。

パイプを使用して、基礎となるキューの実装をロックします。

2.2メソッドの紹介

Queue([maxsize]):共有プロセスのキューを作成します。MAXSIZEはキューに許可されるエントリの最大数です。省略した場合、サイズ制限なし。パイプを使用して、基礎となるキューの実装をロックします。また、サポートも根底にあるパイプにデータキューを転送するプロセスを実行するために必要です。
Qキューは、次の方法の例:

q.get( [ block [ ,timeout ] ] ):プロジェクトqのリターン。qが空の場合、キューが使用可能なアイテムになるまで、このメソッドはブロックされます。ブロッキング動作を制御するためのブロック、デフォルトはTrueです。Falseに設定した場合は、例外Queue.Empty(キューモジュールで定義された)がスローされます。タイムアウトタイムアウトはブロッキングモードで使用するために、任意です。利用可能にする時間間隔内のプロジェクトへの変更がない場合、それはQueue.Empty例外につながります。

q.get_nowait():同じq.get(False)方法。

q.put(item [, block [,timeout ] ] ):キュー内のアイテムです。キューがいっぱいの場合はスペースが利用可能になるまで、このメソッドはブロックされます。挙動制御を遮断するブロックは、デフォルトはTrueです。Falseに設定した場合は、例外Queue.Empty(ライブラリモジュールのキューに定義された)がスローされます。タイムアウトはブロッキングモードでは、時間の利用可能なスペースのための待ち時間の長さを指定します。タイムアウト後Queue.Fullの例外を発生させました。

q.qsize():現在のプロジェクトのキュー正しい数を返します。この関数の結果は、理由を返す間、信頼性の高いものではなく、キューがアイテムを追加または削除することができ、プログラムの後の結果を使用しています。いくつかのシステムでは、この方法では、NotImplementedError例外につながる可能性があります。

q.empty():このメソッドは空の呼び出された場合にはQは、Trueを返します。他のプロセスまたはプロセスがキューに項目を追加する場合、その結果は信頼できません。それはリターンの間で、言うと結果を使用することで、キューが新しいプロジェクトに追加された可能性があります。

q.full():Qがいっぱいの場合、結果は信頼できない(基準とすることができる、なぜならプロセスの真に戻すq.empty()方法)。

2.3その他の方法(理解)

q.close():キューをオフにし、より多くのデータがキューを防止するために添加されます。あなたはこの方法で、データがキューに書き込まれていきますが、まだ書き込まれていないが、この方法が完了するとすぐに閉じますバックグラウンド・プロセスを呼び出すとき。qがガベージコレクトされた場合、それは自動的にこのメソッドを呼び出します。閉じるキューは、データの任意のタイプまたはキュー内のユーザーの異常終了信号を生成しません。ユーザーがブロックされている場合、例えば、get()操作、キューがプロデューサをもたらさない閉じるget()方法がエラーを返します。

q.cancel_join_thread():バックグラウンド・プロセスがプロセスから撤退しませんときに自動的に接続します。これは防ぐjoin_thread()方法ブロックを。

q.join_thread():バックグラウンド・プロセスのキューを接続します。このメソッドは呼び出すために使用されるq.close()方法を、すべての待機中のキューアイテムが消費されています。デフォルトでは、この方法は、Qの原作者ではありませんすべてのプロセスによって呼び出されます。呼び出しq.cancel_join_thread()方法がこのような行為を禁止することができます。

三、キューキュー - の例が示します

しかし、キュー使用3.1を見て

'''
ipc 进程间通讯。使用队列实现
管道:pipe 基于共享的内存空间
队列:pipe+锁 Queue
put:放(可以设置阻塞非阻塞,和等待时间)
get:取(可以设置阻塞非阻塞,和等待时间)
'''
### 语法
q = Queue(3) # 创建队列, 可以设置最大值
## put 放
q.put('你好')     # 往队列中放入值,可以设置阻塞和等待时间,默认:满了再放就会阻塞等待
q.put([1,2,4])
q.put(2)

### 不设置等待时间,队列满了继续放
# q.put(5)    # 阻塞,队列满了,等待队列空了就放进去

## get 拿
print(q.get())  # 获取队列中的内容,可以设置阻塞和等待时间,默认:拿不到内容就会阻塞等待
print(q.get())
print(q.get())

### 不设置等待时间
# print(q.get())  # 阻塞,一直等待获取队列内容

### 设置等待时间
# print(q.get(timeout=2))     # 等两秒,等不到就报错
# q.put(88,timeout=2)   # 不会报错,因为队列中没内容


### 全都设置非阻塞模式
q = Queue(3) # 创建队列, 可以设置最大值
q.put('你好', block=False)     # 设置非阻塞,如果满了再放就会报错
q.put([1,2,4], block=False)
q.put(2, block=False)
# q.put(4, block=False)       # 报错,队列满了

# q.put_nowait('666') # 等同 block = False,报错,队列满了

3.2サブプロセスは、親プロセスにデータを送信します

import time
from multiprocessing import Process, Queue

def f(q):
    q.put([time.asctime(), 'from Eva', 'hello'])  #调用主函数中p进程传递过来的进程参数 put函数为向队列中添加一条数据。

if __name__ == '__main__':
    q = Queue() #创建一个Queue对象
    p = Process(target=f, args=(q,)) #创建一个进程
    p.start()
    print(q.get())
    p.join()

上記キューの簡単なアプリケーションであり、オブジェクトを使用してキューQは、第1のデータキューに入るためにget関数を呼び出します。次に、もう少し複雑な例を見て:バッチ生産データの取得は再びキューになります。

第四に、生産者 - 消費者モデル

並行プログラミングで生産者と消費者の使用パターンは、並行性の問題の大半を解決することができます。生産と消費のプロセスとプロセスを動作させる能力のバランスをとることにより、データ処理プログラムの速度を上げるために、全体的なパターン。

なぜあなたは4.1生産と消費のパターンを使用しますか

世界の生産の過程で生産データの過程で、消費者は、消費データのプロセスです。迅速に処理プロデューサー、そして消費者の処理速度が非常に遅い場合、マルチプロセスの開発では、プロデューサは、生産データを継続するために、処理された消費者を待たなければなりません。消費者の能力がプロデューサーよりも大きい場合には、同じトークンによって、消費者は生産者を待たなければならないでしょう。その生産者と消費者のパターンの導入をこの問題を解決するには。

4.2生産者 - 消費者モデルは何ですか

生産者 - 消費者モデルは、容器の生産者と消費者によって解決される強い結合の問題です。生産者と消費者が直接相互に通信していない、とキューを遮断することによって通信する、消費者を待たずに本番データの処理が完了した後にプロデューサーので、直接スローのブロッキングキューは、消費者がデータへのプロデューサーを見つけることができませんが、キューをブロックから直接採取し、キューが処理能力の生産者と消費者のバランスをとる、ブロッキングバッファーに相当します。

達成するために、4.3キューベースの生産者 - 消費者モデル

ef producer(q,name,food):
    '''生产者'''
    for i in range(10):
        print(f'{name}生产了{food}{i}')
        res = f'{food}{i}'
        q.put(res)


def consumer(q,name):
    '''消费者'''
    while 1:
        res = q.get()
        if res == None:
            break
        print(f'{name}买了{res}')


if __name__ == '__main__':
    q = Queue()   # 使用队列
    p1 = Process(target=producer,args=(q,"xc","意大利面"))
    c1 = Process(target=consumer,args=(q,"haha"))
    p2 = Process(target=producer, args=(q, "xc", "牛肉"))
    c2 = Process(target=consumer, args=(q, "xixi"))
    p3 = Process(target=producer, args=(q, "xc", "可乐"))
    p1.start()
    c1.start()
    p2.start()
    c2.start()
    p3.start()

    p1.join()   # 等待生产者结束
    p2.join()   # 等待生产者结束
    p3.join()   # 等待生产者结束

    q.put(None) # 有几个消费者就要发几个None,让 子进程收到None就结束
    q.put(None) # 有几个消费者就要发几个None,让 子进程收到None就结束

エンド信号必ずしもプロデューサー、あなたが同じを送信することができ、メインプロセスによって作られたどれも、そのプロセスは、信号を送信すべき主な生産の終了後まで待つ必要はありません。子供が受け取ったように、どれも終わっていないいくつかの消費者は、いくつかのどれを作ってはならないがあります

五、JoinableQueueキュー

キューのキューの修正版にJoinableQueueキュー、セマフォと同様の機構を追加します。

5.1 JoinableQueue使用

構文:

  1. オブジェクトの例:q = JoinableQueue()
  2. キュー、1の量に応じた信号の内容を追加します。 q.put(xxx)
  3. キューから取り出しました:q.get()
  4. ミッション、1つの操作量に対応する信号の終了:q.task_done()
  5. セマフォが0でない場合は、カウンタが0〜した後、それは、待機をブロックします。

例:

# JoinableQueue的使用
q = JoinableQueue()

q.put('1')  # +1
q.put('2')  # +1

print(q.get())
q.task_done()   # -1    
print(q.get())
q.task_done()  # -1
q.join() #计数器不为0会阻塞等待 计数器为0后通过

生産者、消費者のモデル・キューによって実現さ5.2 JoinableQueue

def producer(q, name, food):
    '''生产者'''
    for i in range(10):
        print(f'{name}生产了{food}{i}')
        res = f'{food}{i}'
        q.put(res)  # +1


def consumer(q, name):
    '''消费者'''
    while 1:
        res = q.get()
        if res == None:
            break
        print(f'{name}买了{res}')
        q.task_done()


if __name__ == '__main__':
    q = JoinableQueue()     # 使用加了join的队列
    p1 = Process(target=producer, args=(q, "xc", "意大利面"))
    c1 = Process(target=consumer, args=(q, "haha"))
    p2 = Process(target=producer, args=(q, "xc", "牛肉"))
    c2 = Process(target=consumer, args=(q, "xixi"))
    p3 = Process(target=producer, args=(q, "xc", "可乐"))
    # 把消费者变成守护进程,主进程结束,子进程就结束
    c1.daemon = True    # 进程结束,子进程就结束
    c2.daemon = True    # 进程结束,子进程就结束

    p1.start()
    c1.start()
    p2.start()
    c2.start()
    p3.start()

    p1.join()  # 等待生产者结束
    p2.join()  # 等待生产者结束
    p3.join()  # 等待生产者结束

上記のコードは、された子プロセスをデーモンになり、子供の中に消費者のメッセージは、受信するたびにtask_done、その後、主要プロセスの終了を待つ、子プロセスが終了されます

おすすめ

転載: www.cnblogs.com/XuChengNotes/p/11529601.html