マルチスレッドのPythonプログラムでは、あるスレッドが組み込みのraw_input()を使用してコンソール入力を要求することがあります。 raw_inputプロンプトで、シェルで^ Cと打って(つまりSIGINTシグナルで)、プログラムを閉じることができるようにしたいと思います。しかし、子スレッドがraw_inputを実行しているときに^ Cをタイプすると何も起こりません。私がReturnを押すまで(raw_inputから)KeyboardInterruptは発生しません。例えば^C/KeyboardInterruptを持つ子スレッドでPython raw_input()を中断する
は、以下のプログラムで:
import threading
class T(threading.Thread):
def run(self):
x = raw_input()
print x
if __name__ == '__main__':
t = T()
t.start()
t.join()
のタイピング^ Cは、入力が終了した後まで何もしません。しかし、T().run()
(つまり、シングルスレッドの場合:メインスレッドでraw_inputを実行する)を呼び出すだけで、^ Cはすぐにプログラムを終了します。
これは、SIGINTがメインスレッドに送信され、コンソール上のforkedスレッドブロックが読み込まれている間中断されている(GILを待っている)ためです。メインスレッドは、raw_inputが返ってからGILを取得するまでシグナルハンドラを実行しません。 (私が間違っていると私を修正してください - 私はPythonのスレッド実装の専門家ではありません)
SIGINTの処理を許可しながら、raw_inputのような方法でstdinから読み込む方法はありますかメインスレッドによって、プロセス全体を停止させますか?
[Iは、Mac OS Xといくつかの異なるLinuxesで上記の行動を観察してきました。]
編集:私は上記の根本的な問題をmischaracterizedまし。さらに調査すると、シグナルハンドリングを妨げるのは、join()
へのメインスレッドの呼び出しです:Guido van Rossum自身が、the underlying lock acquire in join is uninterruptibleを説明しました。これは、スレッド全体が終了するまで信号が実際に遅延されていることを意味します。つまり、実際にはraw_input
とは何の関係もありません(バックグラウンドスレッドがブロックされているため、結合が完了しません)。
スレッドと中断を単純に結合するのではなく... [boromir.jpg] – JBernardo