非ブロックでなければならない非常に小さなライブラリを 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
それを長時間実行するプロセスにすることだけでした。グリーンレットを生成する必要があるコードは、それ自体が長時間実行されるプロセスであるフレームワーク内で実行されるため、これは間違いなく私の問題を解決します。