次のすべてが当てはまる場合は、魔法のようにパッチが適用されると想定できます。
- I / Oは、標準のPythonまたは/ monkeypatches
socket
の他のものの上に構築されていることを確認してください。ファイル、ネイティブ(C)ソケットオブジェクトなどはありません。eventlet
gevent
aggressive=True
に渡すpatch_all
(またはpatch_select
)、またはライブラリが使用しない、select
または同様のものがないことを確認します。
- ドライバは(暗黙の)内部スレッドを使用しません。(ドライバーが内部でスレッドを使用する場合、機能する
patch_thread
可能性がありますが、機能しない可能性があります。)
よくわからない場合は、テストするのは非常に簡単です。おそらく、コードを読んで解決しようとするよりも簡単です。次のようなことを行うグリーンレットを1つ用意します。
while True:
print("running")
gevent.sleep(0.1)
次に、データベースに対して低速のクエリを実行する別のクエリを用意します。モンキーパッチが適用されている場合、ループするグリーンレットは1秒間に10回「実行中」の印刷を続けます。そうでない場合、プログラムがクエリでブロックされている間、ループするグリーンレットは実行されません。
それで、あなたのドライバーがブロックした場合、あなたはどうしますか?
最も簡単な解決策は、DBクエリに真の同時スレッドプールを使用することです。アイデアは、スレッドプールジョブとして各クエリ(またはバッチ)を起動gevent
し、そのジョブの完了時にグリーンレットブロックすることです。(多くの同時クエリを必要としない非常に単純なケースでは、threading.Thread
代わりにクエリごとにを生成することができますが、通常はそれを回避することはできません。)
ドライバーが重要なCPU作業を行う場合(たとえば、インプロセスキャッシュを実行するもの、またはsqliteなどのインプロセスDBMS全体を使用している場合)、このスレッドプールを実際にプロセスの上に実装する必要があります。 GILはあなたgreenlets
の実行を妨げる可能性があります。それ以外の場合(特にWindowsが気になる場合)は、おそらくOSスレッドを使用することをお勧めします。(ただし、これはできないことを意味しますpatch_threads()
。それが必要な場合は、プロセスを使用してください。)
を使用していてeventlet
、スレッドを使用したい場合は、それと呼ばれる組み込みの単純なソリューションtpool
で十分な場合があります。を使用している場合gevent
、またはプロセスを使用する必要がある場合、これは機能しません。残念ながら、実際のスレッドオブジェクトで(イベントループ全体をブロックせずに)グリーンレットをブロックすることは、との間eventlet
で少し異なりgevent
、十分に文書化されていませんが、tpool
ソースからアイデアが得られるはずです。その部分を超えて、残りはaまたはでタスクを実行するために使用しているだけです(2.xまたは3.1でこれが必要な場合はpypiconcurrent.futures
を参照してください) 。(または、必要に応じて、すぐに使用することも、使用する代わりに使用することもできます。)futures
ThreadPoolExecutor
ProcessPoolExecutor
threading
multiprocessing
futures
WindowsでOSスレッドを使用する理由を説明できますか?
簡単な要約は次のとおりです。スレッドに固執する場合は、ほとんどクロスプラットフォームのコードを記述できますが、プロセスに移動する場合は、2つの異なるプラットフォームのコードを効果的に記述しています。
まず、モジュールのプログラミングガイドラインをお読みくださいmultiprocessing
(「すべてのプラットフォーム」セクションと「Windows」セクションの両方)。幸いなことに、DBラッパーはこれのほとんどに遭遇するべきではありません。を介してプロセスを処理する必要があるだけですProcessPoolExecutor
。また、カーソル操作レベルでもクエリレベルでも、すべての引数と戻り値は、ピクルス化できる単純な型になります。それでも、それはあなたが注意しなければならないことであり、そうでなければ問題にはなりません。
一方、Windowsのプロセス内同期オブジェクトのオーバーヘッドは非常に低くなりますが、プロセス間同期オブジェクトのオーバーヘッドは非常に高くなります。(スレッドの作成も非常に速く、プロセスの作成も非常に遅いですが、プールを使用している場合は重要ではありません。)では、どのように対処しますか?クロスプロセス同期オブジェクトを待機してグリーンレットに信号を送るOSスレッドを作成するのはとても楽しかったですが、楽しみの定義は異なる場合があります。
最後に、 Unix用tpool
に簡単に適応させることができますがppool
、Windowsではより多くの作業が必要になります(そして、その作業を行うにはWindowsを理解する必要があります)。