1

twsited の INotify を使用して /dev ディレクトリを監視し、追加された新しいシリアル デバイスを監視しています。私が現在使用しているコードは以下のようなものです。

notifier = INotify()
notifier.watch(FilePath("/dev"), IN_CREATE, callbacks=[self.created])
notifier.startReading()

def created(self, ignored, path, mask):
    ...
    blocking code
    ...

現時点で私が抱えている問題は、'created' が呼び出されたときにリアクタがブロックされているため、他のネットワーク セッション (同じリアクタに関連付けられた TCP 接続と UDP 接続の両方がある) が 'created' メソッドが呼び出されるのを待たなければならないことです。終了。

「作成された」メソッドをバックグラウンドで実行して、リアクターをブロックしないようにする方法を知っている人はいますか?

ありがとう、

サイモン

4

2 に答える 2

7

Twisted のすべてのイベント ハンドラーは「リアクター スレッド」で実行されます - UDP、TCP、そして inotify です。それらはすべて、ブロックしないことでシステムと協力することが期待されています。したがって、この意味で、これは Twisted で適切なイベント ハンドラーを記述する方法に関する問題であり、特に inotify に関する問題ではありません。

ブロックを回避するための多くのオプションがあります。あなたの質問に答える際の注意点は、正しいオプションが現在のコードが正確にブロックされる理由に依存することです。

ソケット I/O を実行しますか? 代わりに、 Twisted の ノンブロッキング ソケット I/O API を使用してください。

ファイルシステム I/O を実行しますか? ここではスレッドを使用する必要があるかもしれません。非ブロッキング ファイルシステム I/O はスレッドなしでは難しい (おそらく不可能ではない) からです。

SQL データベースと通信しますか? おそらくtwisted.enterprise.adbapiが役に立ちます。

等々。

それがあなたのケースをカバーしているかどうかはわかりませんが、2 つのことを強調します。まず、Twisted プログラムでスレッドを使用することはまったく合理的です。Twisted の多くは存在するので、スレッドを使用する必要はありません、スレッドだけで仕事が完了し、他に何もできない状況になった場合は、スレッドを使用してください (注意して ;)。deferToThreadTwisted には、zeekay によって言及されているように、簡単にするためのヘルパーもあります。次に、タスクに適したソリューションを選択します。すべての「ブロッキング」問題のコレクションは、すべての一般的なプログラミングの問題のコレクションよりもわずかに小さいだけです。考えられる解決策はたくさんあります。スレッドのように、適用範囲が広いように見えるものもありますが、

さらに、詳しい説明については、Twisted: Making code non-blockingをご覧ください。

于 2011-06-01T12:11:40.223 に答える
1

twisted.internet.threads.deferToThreadスレッドでブロッキング コードを実行するために使用できます。

deferToThread(self.created, ignored, path mask)
于 2011-06-01T12:09:10.817 に答える