2011-01-05 2 views
5

ディスカッションSignal handlers and logging in Python Pythonで関数が再入可能であるという質問が私の心の中に浮かび上がってきました。シグナルライブラリー処理のためにPythonでリエントラントな関数はどれですか?

signal library言及:Pythonのシグナルハンドラが非同期に限り Pythonのユーザーが懸念していると呼ばれる ですが

、彼らは だけのPython インタプリタの原子 命令間で発生する可能性があります。これは、 が長い計算中に到着したことを意味します。 の本文には、 の正規表現が大文字の 本文に一致しているなど、Cで完全に実装されている可能性があります( )。再入場は一般的ではありません

logging libraryによって指摘されています

あなたは信号 モジュールを使用して非同期 シグナルハンドラを実装している場合、あなたはから ロギングを使用することができないかもしれませんそのようなハンドラ内で。 これは、スレッド化モジュールのロック実装 が常に リエントラントであるとは限らないため、そのようなシグナルハンドラから を呼び出すことができないためです。

シグナルライブラリーがGIL(グローバルインタプリタロック)について「..アトミック命令の間」と話しているので、ちょっと混乱します。この場合、GILが残されるとすぐに信号が延期され、実行されます。はロックされていませんです。シグナルキューの一種。理にかなっているが、それらは「再入」-limitationとリアル POSIXシグナルハンドラ内で呼び出されていないため延期シグナルハンドラによって呼び出される関数が再入されている場合、それは問題ではありません

: POSIX C 機能の

のみ定義されたリストは、再入 として宣言され、POSIX シグナルハンドラ内で呼び出すことができます。 IEEE Std 1003.1には のリエントラントなUNIX関数があります。 はhttps://www.opengroup.org/です(ログインは が必要です)。

答えて

2

私は何ロギングモジュール非リエントラントを作ること、それは同じハンドラ(そのメッセージが織り込ま得ることはありません)にログインする複数のスレッドを同期させるために(代わりにRLockの)threading.Lockを使用することであると信じています。

これは、ロックを取得したロギングコールがシグナルハンドラによって中断され、シグナルハンドラがログを記録しようとすると、以前のacquireが解放されるのを永久にデッドロックすることを意味します。

これらのロックは、途中でGILとは関係がありません。何らかの形で実装するための「ユーザー作成の」ロックであり、GILはインタープリタによって使用されるロックです(実装の詳細)。

+0

私はPython 2.7.1リリースをチェックしましたが、あなたの前提は間違っています。http://svn.python.org/view/python/tags/r271/Lib/logging/__init__.py?revision=86833&view=markup –

+0

の '_acquireLock()'関数を調べてください。私は修正されました。実際には ' RLock'。それを掘り下げてくれてありがとう。しかし、ドキュメントによれば、実装は必ずしもリエントラントであるとは限りません。「これはスレッドモジュールのロック実装が常に再入可能であるとは限らないからです」(http://docs.python.org/library/logging.html #thread-safety) – albertov

+0

これは私の質問で述べたことです。スレッディングライブラリを使用する各モジュールは、*本物の* POSIXシグナルハンドラで使用される意味では再入可能ではないことがわかります。しかし、Pythonは信号処理を延期しませんか? –

関連する問題