2011-07-06 21 views
6

Windows上にマルチスレッドPythonアプリケーションを作成しています。スレッドを使用しているときにCtrl-Cが機能しません。

ctrl-cを使用してアプリを終了しましたが、threading.Timerインスタンスを追加した後は、ctrl-cの作業が停止しました(または時には時間がかかることがあります)。

どうすればいいですか?
タイマースレッドとctrl-cの関係は何ですか?

UPDATE:
私はPythonのthread documentationで次のが見つかりました:

スレッドは 割り込みと奇妙な相互作用をし:KeyboardInterrupt 例外が 任意のスレッドによって受信されます。 (信号 モジュールが利用可能である場合、メインスレッドに行く 常に遮断する。)

+0

ここにコードを貼り付けることは可能ですか? – Rahul

答えて

4

threading.Thread(したがってthreading.Timer)動作方法は、各スレッドがthreadingモジュールに自分自身を登録することである、と解釈終了時にインタープリタは、インタープリターを終了する前に、登録されたすべてのスレッドが終了するのを待ちます。これはスレッドが実際に実行を終了するように行われ、インタプリタを残して残しておくのではありません。したがって、^ Cを押すと、メインスレッドはシグナルを受信し、終了を決定し、タイマーが終了するのを待ちます。

あなたはthreadingモジュールは、これらのスレッドを待たないが、彼らはインタプリタが終了しながら、Pythonのコードを実行することが起こるならば、あなたは終了時に混乱を招くエラーを取得するために(setDaemon方法)鬼神のスレッドを設定することができます。 threading.Timerをキャンセルして(そしてデーモンを設定しても)、インタプリタが破棄されている間はまだ起きることができます。threading.Timercancelメソッドは起床時に何も実行しないように指示しますが、実際に実行する必要がありますその決定を下すためのPythonコード。

現在のスレッド以外のスレッドを正常に終了する方法はなく、ブロックされたスレッドを確実に中断する方法はありません。タイマーに対するより管理しやすいアプローチは、GUIや他のイベント駆動型システムが提供するイベントループのようなイベントループです。どのようなものを使用するかは、他に何かプログラムによって行われます。

+0

拡大表示ありがとうございます。当分の間、私は問題を解決したスレッドデーモニックをマークしましたが、私はある時点でリファクタリングして適切な終了フローを持つ必要があります。タイマーが同じスレッドに設定されている場合、 – Jonathan

+0

シグナルハンドラは実行されますか?もしそうなら、timer.Cancelをシグナルハンドラで設定することができたら、プロセスは今終了できますか? – Vivek

+0

+1。なぜ、「スレッドを終了するための優雅な方法(現在のもの以外)もなく、ブロックされたスレッドを確実に中断する方法もない」と説明されているリソースがいくつかありますか? – n611x007

2

David Beazleyのプレゼンテーションには、このトピックについての説明があります。 PDFファイルはhereです。 22-25ページ(「Interlude:Signals」から「Frozen Signals」まで)を見てください。

+0

それは確かに洞察力のあるPDFです! – Jonathan

関連する問題