[英]Cannot kill Python script with Ctrl-C
我正在使用以下腳本測試 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()
這是在 Kubuntu 11.10 上的 Python 2.7 中運行的。 Ctrl + C不會殺死它。 我還嘗試為系統信號添加處理程序,但這沒有幫助:
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
為了殺死進程,我在使用Ctrl + Z將程序發送到后台后通過 PID 殺死它,這不會被忽略。 為什么Ctrl + C如此持久地被忽略? 我該如何解決這個問題?
Ctrl + C終止主線程,但是由於您的線程未處於守護程序模式,它們會繼續運行,從而使進程保持活動狀態。 我們可以讓它們成為守護進程:
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
但是還有另一個問題——一旦主線程啟動了你的線程,它就沒有什么可做的了。 所以它退出了,線程立即被銷毀。 所以讓我們保持主線程活着:
import time
while True:
time.sleep(1)
現在它將保持打印“第一”和“第二”,直到您點擊Ctrl + C 。
編輯:正如評論者指出的那樣,守護線程可能沒有機會清理臨時文件之類的東西。 如果需要,則在主線程上捕獲KeyboardInterrupt
並讓它協調清理和關閉。 但在很多情況下,讓守護線程突然死掉可能就足夠了。
KeyboardInterrupt 和信號只有進程(即主線程)才能看到...看看Ctrl-c 即 KeyboardInterrupt 以殺死 python 中的線程
我認為當您希望線程死亡時,最好在線程上調用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()
@Thomas K 答案的改進版本:
is_any_thread_alive()
,它可以自動終止main()
。示例代碼:
import threading
def job1():
...
def job2():
...
def is_any_thread_alive(threads):
return True in [t.is_alive() for t in threads]
if __name__ == "__main__":
...
t1 = threading.Thread(target=job1,daemon=True)
t2 = threading.Thread(target=job2,daemon=True)
t1.start()
t2.start()
while is_any_thread_alive([t1,t2]):
time.sleep(0)
要提防一個簡單的“陷阱”,您確定CAPS LOCK沒有打開嗎?
我在 Pi4 上的 Thonny IDE 中運行 Python 腳本。 啟用CAPS LOCK后, Ctrl + Shift + C被傳遞到鍵盤緩沖區,而不是Ctrl + C 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.