まず、ミューテックス
プロセス間のデータの分離が、直接通信文書のプロセスによって達成することができる共有ファイルシステム、が、問題は、独自のロックに対処しなければなりません。
注:ロックの目的は、データのセキュリティを確保するために、データの同じ部分を変更する複数のプロセスが、同時に唯一の修飾、即ちシリアル変化が、はい、速度は、速度を犠牲に遅いときことを保証することです。
トイレの1.小さな例:誰かがドアロックを見に来たあなたは間違いなくそれをロックする必要があり、トイレは、あなたがドアを開けるのを待って、外で待っされますが、それが出てきた開かれ、人々は次に行きますトイレ。
1インポート処理をマルチプロセッシングから、ロック 2インポートOS 3インポート時間 4 DEF動作(ミューテックス): 5 mutex.acquire() 6プリント( 'タスク[%のS]上厕所' %os.getpid()) 7 time.sleep( 3) 8プリント( 'タスク[%S]上完厕所' %のos.getpid()) 9 mutex.release() 10 __name__ == '__main__'であれば: 11ミューテックス=ロック() 12のP1 =プロセス(目標=作業、引数=(ミューテックス)) 13 P2 =プロセス(目標=仕事、引数=(ミューテックス)) 14のP3 =プロセス(目標=仕事、引数=(ミューテックス)) 15 p1.start() 16枚のP2。開始() 17 p3.start() 18 p1.join() 19 p2.join() 20 p3.join() 21プリント( '主')
第二に、シミュレーションラッシュチケット(また、ミューテックスの原則を利用:LOCKミューテックスを)
インポートJSON 1 2インポート時間 3ランダムインポート 4つのインポートOS インポートプロセスのマルチプロセッシングから5、ロック 6 DEF Chakan(): 7 DIC = json.load(オープン( 'ピャオ'))#最初のチェック票、すなわち、ファイルを開きます 8プリント( '票残り:%s'は%DIC [ 'カウント'])#は、残りの投票を視聴 9購入DEF(): 10 = json.load DIC(オープン('ピャオ')) 。11 DIC IF [」COUNT 「]> 0:チケット番号がある場合は 12 DIC [」カウント「] - = 1つの#は-1内部の値を変更 13 time.sleep(random.randint(1,3))であるチケットシリーズ#を行います最初の操作で行われていない、ので、睡眠(睡眠とランダムに)置き換えます 14 json.dump(DIC、オープン(「ピャオ」、「W」)) 15印刷(「%S購入の成功は」%os.getpid ())#IDは、現在の発券成功 16デフタスク(ミューテックス):#グラブ票 17 chakan()#表示時間我々はすべてが見ることができるので、ロックなし 18 mutex.acquire()#ロック さんが購入する人の背中の上に購入する人を待ってみましょう、いずれかを購入するための19の買い()#を購入する時間 ()#は、ロック解除20 mutex.releaseを :__name__ ==「__main__」の場合21 )22 =ロックミューテックス( 範囲(50)内のI 23 :#は、 50人が投票数訪問することを可能にする 24-p過程=(目標=タスク、引数の=(ミューテックス)) )25 p.startを(
Processオブジェクトの第三に、他のプロパティ
p.daemon:デーモン(デーモンがオープンする前に設定する必要があります):親が死亡した場合、子供にもpは死にました
p.join:メインプロセスを実行する前に終了したp親プロセスの実行と、他のは、親プロセスは、所定の位置にブロックされ、そしてpは、まだバックグラウンドで実行されています。
終了:閉鎖を余儀なく。私はあなたをハングアップする場合は、ハングアップしていない、そしてノーがあります:(Pが閉じたときに、サブプロセスがある場合は、あなたがシャットダウンを強制するために、このメソッドを使用してゾンビプロセス(アナロジーを持つことになり、他の子プロセスが存在しないことを確認してください人の死体は))ハハ、ああ、あなたを与えます
is_alive:シャットダウンプロセスは、それがすぐにシャットダウンされませんので、結果はすぐにまだ生き残ることが確認is_alive
p.joinは():親プロセスpの終了を待って、所定の位置にブロックされた親プロセスであり、pは、まだバックグラウンドで実行されています
p.name:ビュー名
p.pid:ビューID
私たちは、簡単にゾンビプロセスを説明することができます:
子プロセスが完了するまで実行されますが、親プロセスは、回復するためにはまだ子プロセスが実際にはまだ、システムリソースを占有している出口は、このようなサブメニュープロセスが呼び出されていないこの時間があるゾンビプロセスを。
リソースのゾンビプロセスは、システムリソースの無駄が生じ、回復していないので、あまりにも多くのゾンビプロセスは、システムのパフォーマンスの低下につながる、それは硬い⼫プロセスが発生することは避けてください。
マルチプロセッシングからプロセスをインポート1。 2インポートOS 3インポート時間。 4 DEF(ワーク): 5プリント(os.getpid%を'Sが作動している%'()) 6 time.sleep。(3) 7 __name__ == '__main__' IF: 8プロセスP1 =(目標=ワーク) 9つのP2 =処理(目標=ワーク) 10のP3 =処理(目標=ワーク) 11 p1.daemon =真# 12#p2.daemon =真#デーモン(父親の保護者) 13# p3.daemon =真#プライマリプロセスデッド子プロセスが死んでいる(これは、子プロセスを実行しないであろう) 14 p1.start() 15 p2.start() 16 p3.start() 17 18 p3.join() 19 p2.join() 20 p1.join()#の複数の使い果たすメインプログラムの実行に費やした最長時間を待っている参加 21プリント(「メイン」) 22 23# -どのように学びます------ --------- 24#p1.terminate()#強制的に閉じられたプロセスを time.sleep 25#(3) 26#印刷(p1.is_alive())#彼らはまだ生きているかどうかを確認するために 27#プリント(p1.name)#は、プロセス名表示 28#プリント(p1.pid)#ビューのID番号 29#印刷(「メイン」)を
3×3のプロセス間通信(IPC)方法:
一つの方法:キュー(推奨)
プロセス間通信(IPC)を達成するために、それぞれ他のプロセスから単離され、マルチプロセッシングモジュールは、2つの形式サポート:キューおよびパイプラインを、これらの2つの方法は、メッセージパッシングの使用であります
1.キュー:パイプと同様キューは、FIFO要素
注意すべきは、このです:キューは、メモリ操作、出金処理、空のキュー、さらに、キューがブロックされている形態である
2分類キュー
多くのキューが存在しますしかし、すべてのモジュールのキューに頼る
Queue.Queue()#FIFO
queue.LifoQueue()#LIFO
queue.PriorityQueue()#プライオリティキュー
queue.deque()#キューワイヤー
(すなわち、パイプおよびロック方法の底部にある)クラスキューを作成します。
1
2
|
Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,
可以使用Queue实现多进程之间的数据传递。
|
パラメータ説明:
1
|
1
maxsize是队列中允许最大项数,省略则无大小限制。
|
メソッドのはじめに:
1
2
3
4
5
6
7
8
9
|
q.put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为
True
(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为
False
,但该Queue已满,会立即抛出Queue.Full异常。
q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为
True
(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为
False
,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常.
q.get_nowait():同q.get(
False
)
q.put_nowait():同q.put(
False
)
q.empty():调用此方法时q为空则返回
True
,该结果不可靠,比如在返回
True
的过程中,如果队列中又加入了项目。
q.full():调用此方法时q已满则返回
True
,该结果不可靠,比如在返回
True
的过程中,如果队列中的项目被取走。
q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同q.empty()和q.full()一样
|
アプリケーション:
#1は、キューの任意の型に置くことができる 2 FIFO#2 。3マルチプロセッシングインポートプロセスから、キューは 4キューQ =(3) 。5 q.put( 'まず')真#デフォルトブロックを= 6 q.put ( '第2') 。7 q.put( 'THIRD') 。8 。9プリント(q.get()) 10プリント(q.get()) 。11プリント(q.get())
生産者と消費者モデル
並行プログラミングで生産者と消費者の使用パターンは、並行性の問題の大半を解決することができます。生産と消費のスレッドスレッドのバランスをとる能力を加工してデータ処理プログラムの速度を上げるために、全体的なパターン。
なぜ使用の生産者と消費者のパターン
スレッドの世界では、スレッドが本番データのプロデューサーである、消費者は、スレッド消費データです。迅速に処理プロデューサー、そして消費者の処理速度が非常に遅い場合、マルチスレッドの開発では、プロデューサは、生産データを継続するために、処理された消費者を待たなければなりません。消費者の能力がプロデューサーよりも大きい場合には、同じトークンによって、消費者は生産者を待たなければならないでしょう。その生産者と消費者のパターンの導入をこの問題を解決するには。
生産者 - 消費者モデルとは何ですか
生産者 - 消費者モデルは、容器の生産者と消費者によって解決される強い結合の問題です。生産者と消費者が直接相互に通信していない、とキューを遮断することによって通信する、消費者を待たずに本番データの処理が完了した後にプロデューサーので、直接スローのブロッキングキューは、消費者がデータへのプロデューサーを見つけることができませんが、キューをブロックから直接採取し、キューが処理能力の生産者と消費者のバランスをとる、ブロッキングバッファーに相当します。
生産者 - 消費者モデル・キューの実装
プロデューサとコンシューマ(二つの方法)
1、q.put(なし):なし生産者の中に入れて
キューからプロセスマルチインポート 2インポートOS 3インポート時間 。4インポートランダム 。5#最初の生産者と消費者有する 6つの#メーカー製造パン 「7」「を使用する方法に関するこのなしq.put(なし)を挿入問題解決しながら 8が、そこに複数の生産者は、おそらく箱の中に、消費者はより多くのですが、何のパンがあれば 9他の食品がありますが、すでに空示さないんので、あなたが解決することはできません、それは、完璧ではない にも10 JoinableQueue ''解決するために使用することができる'11 DEF Producter(Q)を: 12(10)の範囲でIのためである: 13(2)#パンは、生産プロセスを持っている必要time.sleepして、彼らは眠る 14のres ='パンの%s'は%I#生成あまりパン 15 q.put(RES)#は、バンの内側にあるボックスにそれを生成 \ 033 [44メートル16の印刷( ' %sの033 \製造%S [0メートル' %(os.getpid()、RES)) 、それは生産を終了したものを、時間を知るための17 q.put(なし)#のみプロデューサー(なし以上生産していない現時点では説明に入れて) 消費者はBUN 18# 19デフ消費者を(Q): 20ながらTRUE:消費者は#を食べ続ける場合 RESの=は()である21をq.get 22なしRESの場合は次のとおりです。ボックス内に#を食べるために休憩時間が空の場合は、直接ブレーク 23はtime.sleepある(random.randint(1,3)) 24印刷(「\ 033 [41メートル%sは食べS%\ 033 [0メートル'%(os.getpid()、RES)) 25 IF __name__ ==' __main__「: 26は、Q =キュー()で 27プロセスP1 =(目標= Producter、引数= (Q)) 28プロセスP2 =(目標=コンシューマ、引数=(Q)) 29 p1.start() 30 p2.start() 31 p1.join()である 上記の実行後32 p2.join()#待ちプライマリ実行するプロセス、 33プリント(「プライマリ」)
JoinableQueueを使用して2を
JoinableQueue、からプロセスマルチインポート 2インポートOS 3インポート時間。 4インポートランダム。 5位最初生産者と消費者有する。 6#コンシューマパンを 7 DEF消費(Q): 8 '' '消費者' '' 9、一方真。 :消費者が#食べ続ける場合 )10 q.get RESの=を( 。11 time.sleep(random.randint(1,3)) 12は、プリント( '\ 033 [%S 41M%S食べる\ 033 [0メートル' %です(os.getpid()、RES)) 13 q.task_done()#ミッション(消費者が、私は正しいことを削除したプロデューサー)伝えるために終わった 14#メーカーのパン 15 DEF Producter(q)を: 16 ' 'プロデューサー' '' 17 Iのための範囲である。(5): 18(2)#パンは、製造プロセスを有する必要time.sleepて、彼らは眠る 19のRES = 'パンを%s'は%iは#生成非常に多くのバンズ 20 q.put(RES)#は、内部に行くために箱の中にパンを生産しました 21印刷( '033 \ \ 033 [44メートル%sの製造%S [0メートル「%(os.getpid()、RES)) 22(q.joinある) 23である :24 __name__ == '__main__' IF 25 Q = JoinableQueue () 26のP1 =プロセス(目標= Producter、引数=(Q)) 27 P2 =プロセス(目標=消費者、引数の=(Q)) 28 p2.daemon =真#それがセット消費者を守るために開始する前にプロセスP1、P2が終了オーバーとなり (29 p1.start) 30 p2.start() 31 p1.join()#プロデューサーはなく製パン後(プロデューサの終了を待って、そして消費者がされていること食べて、引っかかって 置く最終消費者)は、32位、さらに何も食べていない生産 33の#は、メインの実行に、上記のプロセスを実行待ち 34印刷(「主」)
複数のプロデューサおよび複数のコンシューマ(二つの方法)
1、q.put(なし):なし生産者の中に入れて
2、利用JoinableQueue
JoinableQueue、からインポートマルチプロセッシング工程 2インポートOS 3インポート時間 。4インポートランダム 。5#最初の生産者と消費者有する 6#コンシューマパンを :7 DEF消費(Q) 。8ながらTRUE: 9 q.get RESの=() time.sleep 10(random.randint(1,3)) 。11プリント( '\ 033 [%S 41M Sは%\ 033 [0メートル食べる' %(os.getpid()、RES))を 12(q.task_doneあります) (私は正しいことを削除した生産指示する消費者)の任務の#エンド 13 DEF product_baozi(q)を: レンジで私のために14(5): 15 time.sleep(2) 16のRES =「バンズ%s」のI%は 17 q.put(RES) 18は、印刷( '\ 033 [%Sの44M製造S%\ 033 [0メートル' %(os.getpid()、RES))である 。19 q.join()#入れていない(なし)、およびフェッチされ、Qのように。(データは完全に取ることはない場合、プロデューサーはオフに終了しません) DEF product_gutou 20である(Q): 21でIのためのものです範囲(5): 22 time.sleep(2)であり、 23は、RESの= 'S骨%' %Iで 24 q.put(RES) 25プリント( '\ 033 [製造44M%S%\ 033 [0メートル' %(os.getpid()、RES)) 26 q.join()である :27 DEF product_doujiang(Q) I 28範囲(5): 29 time.sleep(2) 30 =のRES '乳%S' %のI で31 q.put(RES) 32プリント( '\ 033 [%のSの44M製造Sの%\ 033 [0メートル' %(os.getpid()、RES)) 33(q.joinある) 34がある == IF '__name__ 35 __main__「: 36 JoinableQueue Q =() 37 [#生産に:調理 38は、P1 =プロセス(目標= product_baozi、引数の=(Q))であり (=(Q、)目標= product_doujiang、引数)39プロセスP2 = 40のP3 =プロセス(目標= product_gutou、引数=(Q)) 41である 42#消費者である:商品を食べます彼ら 43のP4 =プロセス(目標=消費者、引数=(Q)) 44のP5 =プロセス(目標=消費者、引数の=(Q)) 45 P4 .daemon = Trueの 46 p5.daemon = Trueを 47#p1.start() 48#p2.start() 49#p3.start() 50#p4.start() 51#p5.start() 52のLi = [P1 、P2、P3、P4、P5] リチウムのI 53: 54 i.start() 55 p1.join() 56 p2.join() 57 p3.join() 58プリント( '主')
第二の方法:パイプ(お勧めしません、あなたが理解することができます)
パイプはキューですが、パイプが自動的にロックされていません
三つの方法:共有データ(推奨されません、あなたが理解することができます)
キューを使用することをお勧めしますので、データなし自動ロック機能を共有します。研究パイプや興味のあるデータを共有することができます