42

ここで私がやろうとしているのは、キーボード割り込みを使用して、プログラム内の進行中のすべてのスレッドを終了することです。これは、スレッドが作成される私のコードの簡略化されたバージョンです。

for i in taskDictionary:
    try:
        sleep(60)
        thread = Thread(target = mainModule.executeThread)
        thread.start()
    except KeyboardInterrupt:
        thread.__stop()

プログラム自体ははるかに複雑で、スレッドに影響を与えるさまざまな変数を考慮し、タスクがスレッド化されずに1つずつ起動されるシーケンシャルモードで起動するオプションもあるため、問題が発生する可能性があります。この小さなバリエーションで、私はちょうど思いついた。私はこれを50/50の結果を生み出す方法で行いました。割り込みは機能しますが、スレッドが正常に終了することはありません。場合によっては、続行しても将来のスレッドの実行を停止することもあれば、割り込みに関する大規模なエラーで終了することもあれば、割り込みがまったく何もしないこともあります。前回これを実行したとき、プログラムは将来のスレッドの実行を停止しましたが、現在のスレッドは停止しませんでした。スレッドが実際に実行されているモジュールに入らずにスレッドを終了する方法はありますか?

4

2 に答える 2

69

同様の質問は、「スレッドを強制終了するにはどうすればよいですか?」です。

スレッド モジュールのロックまたはイベント オブジェクトによって制御される終了ハンドラーをスレッドに作成します。次に、単にロックを解除するか、イベント オブジェクトにシグナルを送ります。これは、処理を停止して正常に終了する必要があることをスレッドに通知します。メイン プログラムでスレッドにシグナルを送信した後は、スレッドがシャットダウンするまで待機するthread.join()メソッドを使用するだけです。main

簡単な例:

import threading
import time

def timed_output(name, delay, run_event):
    while run_event.is_set():
        time.sleep(delay)
        print name,": New Message!"


def main():
    run_event = threading.Event()
    run_event.set()
    d1 = 1
    t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event))

    d2 = 2
    t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event))

    t1.start()
    time.sleep(.5)
    t2.start()

    try:
        while 1:
            time.sleep(.1)
    except KeyboardInterrupt:
        print "attempting to close threads. Max wait =",max(d1,d2)
        run_event.clear()
        t1.join()
        t2.join()
        print "threads successfully closed"

if __name__ == '__main__':
    main()

スレッドを強制終了する機能が本当に必要な場合は、マルチプロセッシングを使用してください。SIGTERM を個々の「プロセス」に送信することができます (threading モジュールと非常によく似ています)。一般的に言えば、スレッド化は IO バウンドの場合に使用され、マルチプロセッシングは真にプロセッサ バウンドの場合に使用されます。

于 2012-07-11T15:54:45.840 に答える