私たちは、コードの複数の知識のスレッドだけでなく、テストのコメントの例を用いて、詳細に説明したようにマルチスレッドのpythonは、マルチスレッド、今日は非常に重要な知識です。
インポートのスレッド
インポートロックをスレッドから、スレッド
インポート時、
「」」
詳細なPythonのマルチスレッド
スレッドとは何ですか?
また、軽量プロセスとして知られているスレッドは、オペレーティングシステムは、それがプロセスに含める、単位プロセスの実際の動作であり、スケジューリング操作が可能な最小単位です。
のプロセスとプロセスを共有するには、システムのリソースを持っていないスレッド、不可欠なリソースの操作に少しだけを持っていますが、それは他のスレッドに属していてもよいです
これは、すべてのリソースを持っています。スレッドが別のスレッドが同じプロセス内で複数のスレッド間で同時に実行することができ作成および破棄することができます
「」」
「」」
なぜマルチスレッドでしょうか?
スレッドは、プログラム内の同時ストリームの実装は無関係です。分離プロセスと比較して、プロセス内のスレッド間の分離の程度が小さく、それらはメモリ、ファイルハンドルを共有しました
そして、他のプロセスが必ず明記してください。
スレッドの分割は、その結果、マルチスレッド・プログラムの同時実行を高くプロセスより小さいスケールため。プロセスは、実行のプロセスに別個のメモリユニットを有しており、複数のスレッドで共有します
メモリは、大幅プログラムの効率を高めます。
スレッドは、共通している複数のスレッドが仮想空間を共有するプロセスと同じプロセス内のスレッドに起因して、プロセス、より高い性能を有します。共有環境スレッド
プロセス・コード・セグメント、全プロセスデータ、これらの共有データの使用を含め、スレッド間で通信することは容易です。
あなたは、オペレーティング・システム・プロセスを作成すると、改革のプロセスは、別のメモリ領域に割り当てられ、多くのリソースを割り当てるが、スレッドを作成するためにはるかに簡単ですしなければなりません。したがって、マルチスレッドの使用
パフォーマンスの比率がより高いことが複数のプロセスの同時使用を実現しています。
「」」
「」」
要約すると、マルチスレッドプログラミングを使用するには、以下のような利点があります。
あなたは非常に簡単にスレッド間のプロセス間のメモリが、共有メモリを共有することはできません。
あなたは、プロセスへの再割り当てシステムリソースへの必要性、オペレーティングシステムプロセスを作成しますが、コストははるかに少ないスレッドを作成した場合。したがって、マルチタスクの同時実行を達成するためにマルチスレッドを使用することは、複数のプロセスを使用するよりもより効率的です
Python言語のサポートは、内蔵のマルチスレッド機能ではなく、単に基礎となるオペレーティングシステムのスケジューリングなどよりも、Pythonでマルチスレッドプログラミングを簡素化します。
「」」
「」」
一般的な方法を作成します。
「」」
#デフの実行(N):
#プリント( 'タスク'、N)
#time.sleep(1)
#プリント( '2S')
#time.sleep(1)
#プリント( '1S')
#time.sleep(1)
#プリント( '0')
#time.sleep(1)
#
#もし__name__ == '__main__':
#T1 = threading.Thread(目標=ラン、引数=(「T1」))#対象関数名(ない機能)を実行する、引数タプルの形式で対応するパラメータの関数です。
#T2 = threading.Thread(目標=ラン、引数=( 'T2'))
#t1.start()
#t2.start()
「」」
カスタムスレッドは:クラスThreadのrunメソッドの再構築は、Threadクラスの継承は、その性質上、定義することthreading.Threadです
「」」
#クラスMyThread(threading.Thread):
#デフ__init __(自己、N):
#スーパー(MyThread、自己).__のinit __()#機能再建の実行を記述する必要があります
#self.n = N
#
#デフ(自己)を実行します。
#プリント( 'タスク'、self.n)
#time.sleep(1)
#プリント( '2S')
#time.sleep(1)
#プリント( '1S')
#time.sleep(1)
#プリント( '0')
#time.sleep(1)
#
#もし__name__ == '__main__':
#T1 = MyThread( 'T1')
#T2 = MyThread( 'T2')
#t1.start()
#t2.start()
「」」
デーモンスレッド
、すべての子スレッドがメインスレッドデーモンスレッドになってきたここでは、setdaemon(true)を使用し、次の例で、
メインスレッドの終わりには、子スレッドは、最後に来るときにそのときのメインスレッドの終了、全プログラムが終了します。
メインスレッドに関係なく、スレッドの実装である、いわゆる「スレッドガード」、限り、子スレッドが終了し、他のメインスレッドが終了すると、メインスレッドが閉じられます。言い換えれば、メインスレッドが消灯するデーモンスレッドの実行を完了を待ちません。
「」」
#デフの実行(N):
#プリント( 'タスク'、N)
#time.sleep(1)
#プリント( '3S')
#time.sleep(1)
#プリント( '2S')
#time.sleep(1)
#プリント( '1S')
#
#もし__name__ == '__main__':
#T = threading.Thread(目標=ラン、引数=( 'T1'))
#t.setDaemon(真)
#t.start()
#プリント( '終了')
「」」
最後は、子スレッドが即座に終了する時にデーモンスレッド、メインスレッドを設定した後の結果でわかるように、実行されません
「」」
「」」
子スレッドが終了するため、メインスレッドが待機
子スレッドの実行のためにメインスレッドが待機するように、スレッドの終了後にメインスレッドとその後、終了をガードを実行するために、我々は、メソッドへの参加を使用することができます
「」」
#デフの実行(N):
#プリント( 'タスク'、N)
#time.sleep(2)
#プリント( '5S')
#time.sleep(2)
#プリント( '3S')
#time.sleep(2)
#プリント( '1S')
#もし__name__ == '__main__':
#T = threading.Thread(目標=ラン、引数=( 'T1'))
デーモンスレッドを処理するスレッドの#T.setDaemon(真)#)が(開始前に設定する必要があります
#t.start()
#T.join()#は、子スレッドの終了のためにメインスレッドを待機を設定します
#プリント( '終了')
「」」
マルチスレッドで共有グローバル変数
実行の最小単位と、プロセス実行部スレッド、システムの処理リソースを割り当てるので、同じプロセス内の複数のスレッドが共有リソースであります
「」」
#= 100 g_num
#デフWORK1():
#グローバルg_num
範囲内のiについて#(3):
#G_num + 1 =
#印刷( 'WORK1 g_numである:%D' %g_num)
#
#デフWORK2():
#グローバルg_num
#印刷( 'WORK2 g_numである:%D' %g_num)
#
#もし__name__ == '__main__':
#T1 = threading.Thread(目標= WORK1)
#t1.start()
#time.sleep(1)
#T2 = threading.Thread(目標= WORK2)
#t2.start()
「」」
それはスレッド間のランダムなスケジュールであり、各スレッドは唯一のN小節を行った後に行うことができるので、複数のスレッドが同時に同じデータを変更する場合、ダーティデータは、起こり得ます
だから、一度に1つのスレッドが操作を実行することができますスレッドロックがありました。排他的な必要に応じて、ロック複数のリソースをロックするためのスレッド・ロックは、次のコードとして定義することができます
特定のリソースは、すべてのロックがリソースをロックすることができたとき、あなたが別のロックを使用するよりも、このようにドアロックと同じにすることができます。
それは、スレッド間のランダムなスケジュールであるため、オブジェクトが十分に保護されていない場合は、複数のスレッドが同時に、オブジェクトが動作している場合は、手続きの予期しない結果を引き起こす可能性があり、
したがって、我々はまた、「スレッドセーフ」と呼ば
このような状況を防ぐために、ミューテックスのロック(ロック)がありました
「」」
仕事DEF#():
いいえ、全体的な#ありません
#lock.acquire()
#TEMP = N
#time.sleep(0.1)
#N = TEMP-1
#lock.release()
#
#
#もし__name__ == '__main__':
#ロック=ロック()
#N = 100
#1 = []
範囲内のiについて#(100):
#P =スレッド(ターゲット=仕事)
#l.append(P)
#p.start()
リットルでpの#:
#p.join()
「」」
再帰的ロック:RLcokクラスの使用およびLockクラスとまったく同じ、それは、ネストされたサポートし、複数のロックが解除されていない場合、一般的にRLOCKクラスを使用します
「」」
#デフFUNC(ロック):
#グローバルgl_num
#lock.acquire()
#Gl_num + 1 =
#time.sleep(1)
#印刷(gl_num)
#lock.release()
#
#
#もし__name__ == '__main__':
#= 0 gl_num
#ロック= threading.RLock()
範囲内のiについて#(10):
#T = threading.Thread(目標= FUNC、引数=(ロック))
#t.start()
「」」
セマフォ(BoundedSemaphoreクラス)
ミューテックス同時にセマフォが、このようなピットトイレ3などのデータを変更するスレッドの特定の数が許可されている間、データを変更する唯一のスレッドを可能にしながら、
それはトイレに3人の最大を可能にする、人々は再入力するために、裏返しに誰かの後ろに待たなければなりません
「」」
#デフ(nは、セマフォ)を実行します。
#Semaphore.acquire()#ロック
#time.sleep(3)
#プリント( 'スレッドを実行します:%sの\ n' の%n個)
#Semaphore.release()#リリース
#
#
#もし__name __ == '__main__':
#のNum = 0 より良いhttp://www.zzzy120.com/ある鄭州群集病院
同時に実行するための5つのスレッドの#セマフォ= threading.BoundedSemaphore(5)#最大
範囲内のiについて#(22):
#T = threading.Thread(目標=ラン、引数=( 'T-%S' %I、セマフォ))
#t.start()
!threading.active_countしばらく#()= 1:
# パス
# そうしないと:
#プリント( '----------すべてのスレッドが行わ-----------')
「」」
制御の他のスレッドを実行するためにメインスレッドのイベントのPythonのスレッドは、イベントは、いくつかの方法は主に以下を提供する、単純なスレッド同期オブジェクトです。
フラグがFalseに設定されているクリア
Trueにフラグセット
is_setフラグか否かを判断します
検出されないフラグの状態がブロックされている場合、待機は、リスニングフラグだっただろう
イベント処理メカニズム:値がFalseである場合にグローバルフラグ、フラグを定義し、次いでevent.wait()はフラグ値がTrueである場合にブロックされ、
event.wait()がブロックされなくなりますので、
「」」
イベント= threading.Event()
デフライター():
カウント= 0
event.set()#最初の緑色の光人々へ
真の中に:
<5であれば数<= 10:
event.clear()#赤色光、クリアフラグ
印刷( "\ 33 [41; lmred光であるに... \ 033 [0メートル]")
elifの数> 10:
event.set()#グリーン、セットフラグ
カウント= 0
そうしないと:
印刷( '\ 33 [42; lmgreen光が上に... \ 033 [0メートルです')
time.sleep(1)
カウント+ = 1
デフ車(名):
真の中に:
event.is_set()場合:#フラグか否かを判断します
印刷( '[%s]を実行している.....' %名)
time.sleep(1)
そうしないと:
( '待って、赤い光を見ている[%s]の...' %名)を印刷
event.wait()
印刷( '行くの開始、[%s]は緑色のライトがオンになっている...' %名)
#のstartTime = time.time()
光= threading.Thread(目標=ライター)
light.start()
車= threading.Thread(対象=車、引数=( 'MINT'、))
car.start()
endTimeは= time.time()
#プリント( '用时:'、endTimeは-たstartTime)
「」」
GILのグローバルインタープリタ
非Python環境では、シングルコアの場合は、1つのタスクのみを実行する一方で。場合、マルチコアが同時に複数のスレッドをサポートすることができます。しかし、Pythonで、ノーどのように多くのコアを重要で
同時に、1つのだけのスレッドを実行することができます。この理由は、GILの存在によるものです。
GILグローバルインタプリタ全体で、Pythonのソースが作られたデータセキュリティ上の決定のために、設計の始まりと考えられています。あなたが実行したいスレッドは、あなたが最初にGILを取得する必要があり、我々はできます
GILは「合格」として見られ、Pythonのプロセスにおいて、GILは唯一のものです。スレッドのパスを取得し、pythonのプロセスは、GILは唯一のものです、
CPUに許可されていないスレッドを渡す取得できません。彼は直接話すことができないので、GILは唯一、CPythonのコールは言語、Cネイティブスレッドであるという理由だけではCPython
CPUなどが、我々はデータのみを取得するために同じ時間だけつのスレッドGIL保証を使用することができます。pypyとJPythonのではありませんGILであります
マルチスレッドを使用した場合のpythonは、ネイティブプロセスは、C言語と呼ばれています。
「」」
「」」
コードの実行効率の異なるタイプのPythonは異なっています
図1に示すように、CPU集中コード(様々なループ処理、計算、など)は、この場合には、複数の計算ので、技術がすぐその後GILの始動閾値に達するマダニ
リリースしてから(スイッチを前後もちろんの複数のスレッド、リソースを消費する必要性を)競争は、そのCPU集約型コード用のPythonで複数のスレッドが友好的ではありません。
2、IO集中コード(ファイル処理、ウェブクローラデザインファイルの読み出しおよび書き込み動作)は、効果的にマルチスレッドの効率を向上させることができる(IO操作は、IOの単一スレッドを待つ必要があります
時間の無駄な浪費をもたらし、そして待機が自動的にスレッドBに切り替えるスレッドAで複数のスレッドを開くことができ、あなたは、プログラムの実行を向上させることができ、CPUリソースを無駄にすることはできません
効率)。IO集約型のコードのための、より親しみやすいマルチスレッドのpythonだから。
「」」
「」」
主に、我々はI / O集約的計算集約的に分割し、ハンドオーバにマルチスレッドのタスクはI / Oスイッチおよびタイムスイッチに分割され、タスクの種類に依存します。タスクはに属している場合はI / O集約的であり、
マルチスレッドを使用せずに、我々は、I / O操作はフロントI / Oタスクを待つためにバインドされて行ってI / Oタスクが待機プロセスで行うことができるの背後に完了すると、CPUは待機中です
その後、ちょうど別のI / Oタスクに切り替わるように、そして、マルチスレッド状態の場合、。あなただけのCPUがアイドル状態である避けるためにCPUを活用して、効率を向上させることができますので。しかし
タスクは、コンピューティング型のマルチスレッド化されている場合、CPUはスイッチスレッドとCPUにタイムスイッチをマルチスレッド方法を取るために、一定時間後までその作業を行っています作業状態にされています、
タスクを切り替えるとき、パフォーマンス、マルチスレッド反対を改善しないこのような状況でも、パフォーマンスの低下をもたらす、時間とリソースの浪費をもたらすことができます。これは、2つのマルチスレッドの結果、上記説明できないことによって引き起こされます。
結論:I / O集約型のタスクは、マルチスレッド、マルチプロセス+コルーチン方法を用いてもよい推奨(例えば:多目的データクローラは、マルチスレッド処理をクロール)、計算集約型のタスクのために、この時点ではないパイソン適用されます。
「」」