130

次のスクリプトを使用してPythonスレッドをテストしています。

import threading

class FirstThread (threading.Thread):
    def run (self):
        while True:
            print 'first'

class SecondThread (threading.Thread):
    def run (self):
        while True:
            print 'second'

FirstThread().start()
SecondThread().start()

これは、Kubuntu11.10のPython2.7で実行されています。Ctrl+Cそれを殺すことはありません。また、システム信号のハンドラーを追加しようとしましたが、それは役に立ちませんでした。

import signal 
import sys
def signal_handler(signal, frame):
    sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)

Ctrlプロセスを強制終了するために、プログラムを+でバックグラウンドに送信した後、PIDで強制終了Zします。これは無視されません。Ctrl+Cがこれほど永続的に無視されるのはなぜですか?どうすればこれを解決できますか?

4

5 に答える 5

206

Ctrl+Cメインスレッドを終了しますが、スレッドはデーモンモードではないため、実行を継続し、プロセスを存続させます。それらをデーモンにすることができます:

f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()

しかし、別の問題があります。メインスレッドがスレッドを開始すると、他に何もすることができなくなります。したがって、それは終了し、スレッドは即座に破棄されます。それでは、メインスレッドを存続させましょう。

import time
while True:
    time.sleep(1)

Ctrl+を押すまで、「first」と「second」を出力し続けますC

編集:コメント投稿者が指摘しているように、デーモンスレッドは一時ファイルなどをクリーンアップする機会を得ることができない場合があります。それが必要な場合はKeyboardInterrupt、メインスレッドをキャッチして、クリーンアップとシャットダウンを調整します。しかし、多くの場合、デーモンスレッドを突然停止させることで十分でしょう。

于 2012-08-05T11:30:20.370 に答える
8

KeyboardInterruptとシグナルはプロセス(つまりメインスレッド)によってのみ見られます... Ctrl-c、つまりPythonでスレッドを強制終了するKeyboardInterruptを見てください

于 2012-08-05T11:25:21.570 に答える
7

join()スレッドが死ぬと予想されるときにスレッドを呼び出すのが最善だと思います。私はあなたのループを終了するように自由に変更しました(そこに必要なクリーンアップの必要性を追加することもできます)。変数dieは各パスでチェックされ、それが のTrue場合、プログラムは終了します。

import threading
import time

class MyThread (threading.Thread):
    die = False
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run (self):
        while not self.die:
            time.sleep(1)
            print (self.name)

    def join(self):
        self.die = True
        super().join()

if __name__ == '__main__':
    f = MyThread('first')
    f.start()
    s = MyThread('second')
    s.start()
    try:
        while True:
            time.sleep(2)
    except KeyboardInterrupt:
        f.join()
        s.join()
于 2019-04-03T18:38:58.840 に答える