計算集約的なタスクのために、何のアクションがタイムアウトするまで、CPUを占有することができなかった、計算集約型のタスクの効率を改善する方法はありませんマルチコアCPUの並列実行するように、GILない限り、除去ロック。
それはどのように効率を向上させることができますか?あなたがスレッドにIO操作を監視することができると思う場合は、他のコンピューティングタスクへの自発的なスイッチのアプリケーションは、CPUを維持することができないのですか?全く
= + 2、タスクの切り替えを実行し、状態を保存することができます解決策を見つけるために長いような状態を切り替える同時タスクを保存し、それは同時に、ねじ実現することができます
このような特徴を持っているPythonのジェネレータ、次の各呼び出しは、タスクを切り替えることができますことを意味し、コードジェネレータの機能を実行するために戻り、最後の実行の結果に基づいて、発電機が自動的になることを意味しています状態を保存!
私たちは、同時実行を実現するために発電機を使用することができて以来。
DEFのTASK1(): しばらく真: 降伏 印刷(" タスク1 RUN " ) DEFのタスク2(): G = TASK1() しばらく真: 次の(G) を印刷(" タスク2 RUN " ) タスク2() の同時実現が、ちょうどこの効率への影響は、良いか悪いですか?テストするために #ハンドオーバの直接シリアル同時実行を使用してタスクジェネレータを計算する2は呼び出し インポート 時間 DEF )タスク1(: A = 0 のための I にレンジ(10000000 ): A + =I 収量 DEF Task2の(): G = タスク1() B = 0 のための I における範囲(10000000 ): Bの + = 1。 次に(G) Sは、 = time.time() Task2の() プリント(" 同時実行時間"、時間.time() - S) #同時必要性を切り替えて保存するので、かなり複雑よりも、直列2高効率化を行ってシングルスレッドコンピューティングタスク DEF タスク1を(): A = 0 のための I におけるレンジ(10000000 ): A + = I DEF Task2の(): B = 0 のための I におけるレンジ(10000000 ): Bの + 1 =。 Sは = time.timeを() タスク1() Task2の() 印刷(" シリアル実行時間"、time.time() - S)
私たちは純粋なコンピューティングタスクのために見ることができますが、約半分低下したシングルスレッドの同時実行効率を作るので、このプログラムは不要という点で、純粋な計算タスクのためにあります
私たちは、10個のタスクがそれを切り替える必要がある場合は、想像できない、コードの構造は非常に混乱して切り替えることが利回りを使用して、上記のコードであるように並行プログラムに利益をもたらすかを考えていないでしょう!だから、特別な誰かがモジュールgreenletを持つことになりますパッケージを、得ました
DEF タスク1(名): 印刷(" %Sタスク1 runl "%の名称) g2.switch(名)#のスイッチ2タスクに 印刷(" タスク1 RUN2 " ) g2.switch() #の2タスクにスイッチを DEF Task2の(名前を) : 印刷(" %S Task2のrunl "%の名前) g1.switch()#1 。タスク1のスイッチ プリント(" Task2のRUN2 " ) G1 = greenlet.greenlet(タスク1) G2 =greenlet.greenlet(タスク2) g1.switch(" ジェリー")#のタスクパラメータ
今、私たちは、検出するためのプログラムが必要とIOは、そうgeventデビューシングルスレッドの同時実行を可能にします
オペレーティング・システムのスケジューラによって制御されるカーネル・レベルに属する1 Pythonのスレッド、すなわち、(例えば、単一スレッドの実行時間が長すぎるか、Ioは、CPUがアクセス許可、他のスレッドのスイッチング動作を実行引き渡すことを余儀なくされるであろう遭遇する)
開口部2は、内側RAねじIOのチェンイベントは、効率向上のために、アプリケーションレベル(よりむしろオペレーティングシステム)制御スイッチからなり(非独立ハンドオーバ及び効率を!!! IOオペレーション)
オーバーヘッドを切り替える1.コルーチンは、プログラムに属するスイッチングレベル小さい、オペレーティングシステムが完全に知覚不可能であるため、より軽量
効果は、CPUの使用を最大にするために、単一のスレッド2で同時に達成することができます
次のような欠点があります:
1.コルーチンの性質はシングルスレッドであり、マルチコアは、プログラムが効率最大化するために、各スレッドよりオープンなプロセスは、各プロセス内のオープン複数のスレッド、オープンコルーチンであってもよいし、使用することができない
2コルーチンの性質コルーチン輻輳が発生すると、スレッド全体をブロックしますので、それは、シングルスレッドであります
輸入gevent、SYS から gevent 輸入猿#导入猿补丁 monkey.patch_all() #打补丁 インポート時 の印刷(のsys.path) DEF :タスク1() 印刷(" タスク1の実行" ) #1 gevent.sleep(3) time.sleep (3 ) 印刷(" タスク1オーバー" ) デフタスク2(): プリント(" タスク2ラン" ) #1 gevent.sleep(1) time.sleep(1) プリント(" Task2のオーバー" ) G1 = gevent.spawn(タスク1) G2 = gevent.spawn(Task2の) #1 gevent.joinall([G1、G2]) g1.join() g2.join() #は、上記のコードを実行します出力は、任意のニュース見つけることができません #をメインスレッドがダウンしていきますので、コルーチンのタスクが非同期に提出されているためであるが、一度メインスレッドの最後の行が終わって、終わっ #はコルーチンタスクが来なかった主導しましたそして実行は、それが終了すると、メインスレッド待ちコルーチンタスクに参加する時間でなければならないので、生きている保つために、メインスレッドである #はメインスレッドがそれの終わりを意味していない場合も、メインスレッドが生存していることを確認する必要がありコルーチンを使用する際に従います参加呼び出す必要があります
それは注意する必要があります。
1.タスクコルーチンを終了するメインスレッドは即座に終了する場合。
原理2.monkeyパッチは自動切替IOを達成するために、詐欺を犯している非ブロッキング修飾方法を、ブロックの元の方法を置き換えることです
#Myjson.py DEF ダンプ(): 印刷(" 機能を交換したダンプ" ) DEFの負荷(): 印刷するには(" ロード機能が置き換えられます" ) #のtest.pyの インポートmyjson インポートJSON #のパッチ機能 DEFの(monkey_pacth_json ): json.dump = myjson.dump json.load = myjson.load #1 パッチ monkey_pacth_json() #のテスト json.dump() json.load() #の出力: #ダンプ機能が置き換えられ #load関数が置き換えられます