4

非ブロックでなければならない非常に小さなライブラリを Python で実装する作業を行っています。

一部の製品コードでは、ある時点で、このライブラリへの呼び出しが行われ、独自の作業を行う必要があります。最も単純な形式では、サービスに情報を渡す必要がある呼び出し可能オブジェクトになります。

この「サービスに情報を渡す」ことは集中的なタスクではなく、おそらくデータを HTTP サービスなどに送信します。また、並行である必要も、情報を共有する必要もありませんが、ある時点で、場合によってはタイムアウトで終了する必要があります。

私はthreading以前にモジュールを使用したことがあり、使用するのに最も適しているように思えますが、このライブラリが使用されるアプリケーションは非常に大きく、スレッドの制限に達するのが心配です.

ローカル テストでは、生成された約 2500 スレッドでその制限に達することができました。

(アプリケーションのサイズを考えると) その制限に簡単に到達できる可能性は十分にあります。また、キューにタスクを高速で配置することのメモリへの影響を考えると、キューの使用にうんざりしています。

私も見ましgeventたが、何らかの作業を行い、参加せずに終了する何かを生成できる例は見当たりませんでした。私が経験した例では.join()、スポーンGreenletされたものまたはグリーンレットの配列を呼び出しています。

実行中の作業の結果を知る必要はありません。発火して HTTP サービスとの通信を試み、通信しない場合は適切なタイムアウトで終了する必要があります。

のガイド/チュートリアルを誤解していgeventませんか? 〜2500の制限に達することができない、完全に非ブロッキングの方法で呼び出し可能なものを生成する他の可能性はありますか?

これは、期待どおりに機能する Threading の簡単な例です。

from threading import Thread


class Synchronizer(Thread):


    def __init__(self, number):
        self.number = number
        Thread.__init__(self)

    def run(self):
        # Simulating some work
        import time
        time.sleep(5)
        print self.number

for i in range(4000): # totally doesn't get past 2,500
    sync = Synchronizer(i)
    sync.setDaemon(True)
    sync.start()
    print "spawned a thread, number %s" % i

そして、これは私がgeventで試したことです。ここでは、ワーカーが何をしたかを確認するために最後に明らかにブロックします:

def task(pid):
    """
    Some non-deterministic task
    """
    gevent.sleep(1)
    print('Task', pid, 'done')


for i in range(100):
    gevent.spawn(task, i)

編集: 私の問題は、gevent. コードは実際にスレッドを生成してThreadいましたが、スクリプトが何らかの作業を行っている間に終了することも妨げていました。

geventを追加しない限り、上記のコードでは実際にはそれを行いません.join()。生成されたグリーンレットでコードが何らかの作業を行うのを確認するために私がしなければならなかったことは、geventそれを長時間実行するプロセスにすることだけでした。グリーンレットを生成する必要があるコードは、それ自体が長時間実行されるプロセスであるフレームワーク内で実行されるため、これは間違いなく私の問題を解決します。

4

3 に答える 3

5

Nothing requires you to call join in gevent, if you're expecting your main thread to last longer than any of your workers.

The only reason for the join call is to make sure the main thread lasts at least as long as all of the workers (so that the program doesn't terminate early).

于 2012-07-07T17:46:12.407 に答える
0

Pythonでの非同期/マルチプロセッシングについてで説明したように、asyncoroフレームワークは非同期の並行プロセスをサポートします。数万または数十万の並行プロセスを実行できます。参考までに、100,000の単純なプロセスを実行するには約200MBかかります。必要に応じて、システムの残りの部分のスレッドとコルーチンを非同期で混合できます(ただし、スレッドとコルーチンは変数を共有しませんが、コルーチンインターフェイス関数を使用してメッセージなどを送信します)。

于 2012-07-13T01:28:39.237 に答える
0

接続されたパイプなどを使用してサブプロセスを生成し、呼び出し可能ではなく、データをパイプにドロップして、サブプロセスに完全に帯域外で処理させてみませんか。

于 2012-07-08T15:08:51.120 に答える