2009-06-26 12 views
2

私はTwistedフレームワークを使用しており、RPCを非同期で取得しています。私は2秒ごとにタスクを実行し、その間に眠る別の機能を持っています。これはreactor.callInThreadによって呼び出されます。これらは共有リソースに依存するので、スレッドセーフな方法でそれらにアクセスする必要があります。重大なセクション/ミューテックス/ロックをねじれた状態で使用するにはどうすればよいですか?Pythonでミューテックスをひねりました

答えて

2

スレッドをねじれて使用することはできますが、ねじれた通常のイディオムは、スレッドを1つ使用してRPCを非同期的に行うことです。それはその利点の一つです。ねじれたフレームワークは原子炉を作動させ、RPC結果が得られるとハンドライベントを呼び出します。コードが実行され、ハンドラが終了すると、制御は原子炉に戻り、コードを準備した次のハンドラを呼び出します。したがって、パラレルで多くのことが行われていても、ツイストでは一度に1つの関数だけが実行されるため、ミューテックスは必要なく、状態変数を維持するだけでコールバックが現在のコンテキストを知るようにする必要があります操作で十分です。

スレッドを明示的に作成し、ねじれフレームワークを実行している場合は、おそらくStandard Python Mutexのようなものが必要ですが、主なReactorコールバックスレッドがmutexを待っていないように注意する必要があります原子炉内のコールバックがブロックされないような長さの時間。

+0

hmm ok。さて、具体的には、「reactor.callInThread」の結果として実行される関数呼び出しが1つあります。この関数は2秒ごとに何かを行います。どのように原子炉はそれを処理するのですか?私はRPCがその機能が何かをやっていると同時に実行されていないことを確認したい。 –

+0

hah - 代わりに、タスクを使用する答えです.LoopingCall? –

+0

パフォーマンス(CPUスケーリングなど)の理由でマルチスレッド・アプローチを使用しておらず、他のスレッドの関数が(リアクタ・スレッドをブロックするために)終了せずに長時間実行されない場合は、受け入れられる。正直なところ、スレッド化されたアプローチが必要な場合、ミューテックスを行う正しい方法は、リアクタースレッドがブロックされないためです。 – bdk

0

Twistedを使用すると、イベントドリブンコードを1つのスレッドに書き込むことができます。複数のイベントは安全な問題で標準のPythonのスレッドセーフではないデータ構造に書き込むことができ、スレッドセーフでないデータ構造はmutexとして使用できます。 スレッドを使用し始める場合は、これらのことについて心配する必要があります。しかし、あなたはそれらを使う必要はありません。

コメント:あなたのタスクにtask.LoopingCallまたはreactor.CallLaterを使用します。 time.sleep()を呼び出さないで、適切なタイミングで原子炉にタスクを呼び出させます(そして、その間に他の作業を行います)。 RPCが来たらそれに応答します。

コードを一度に実行するスレッドは2つありません。ただし、コールバックが呼び出される順序はわかりません。コントロールをDeferredに放棄すると、アプリケーション状態は戻ってくるまでに変更された可能性があります。

関連する問題