我正在运行这个简单的代码:
import threading, time
class reqthread(threading.Thread):
def run(self):
for i in range(0, 10):
time.sleep(1)
print('.')
try:
thread = reqthread()
thread.start()
except (KeyboardInterrupt, SystemExit):
print('\n! Received keyboard interrupt, quitting threads.\n')
但是当我运行它时,会打印
$ python prova.py
.
.
^C.
.
.
.
.
.
.
.
Exception KeyboardInterrupt in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
实际上python线程会忽略我的 Ctrl + C 键盘中断而不会打印Received Keyboard Interrupt
。为什么?这段代码有什么问题?
答案 0 :(得分:58)
尝试
try:
thread=reqthread()
thread.daemon=True
thread.start()
while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
print '\n! Received keyboard interrupt, quitting threads.\n'
如果没有调用time.sleep
,主要进程过早地跳出try...except
块,因此KeyboardInterrupt
未被捕获。我的第一个想法是使用thread.join
,但这似乎阻止了主进程(忽略KeyboardInterrupt),直到thread
完成。
thread.daemon=True
导致线程在主进程结束时终止。
答案 1 :(得分:9)
总结the comments中建议的更改,以下内容适用于我:
try:
thread = reqthread()
thread.start()
while thread.isAlive():
thread.join(1) # not sure if there is an appreciable cost to this.
except (KeyboardInterrupt, SystemExit):
print '\n! Received keyboard interrupt, quitting threads.\n'
sys.exit()
答案 2 :(得分:4)
轻微修改ubuntu的解决方案。
按照Eric的建议删除tread.daemon = True并用signal.pause()替换sleep循环:
import signal
try:
thread=reqthread()
thread.start()
signal.pause() # instead of: while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
print '\n! Received keyboard interrupt, quitting threads.\n'
答案 3 :(得分:0)
我的(hacky)解决方案是像这样修补Thread.join()
:
def initThreadJoinHack():
import threading, thread
mainThread = threading.currentThread()
assert isinstance(mainThread, threading._MainThread)
mainThreadId = thread.get_ident()
join_orig = threading.Thread.join
def join_hacked(threadObj, timeout=None):
"""
:type threadObj: threading.Thread
:type timeout: float|None
"""
if timeout is None and thread.get_ident() == mainThreadId:
# This is a HACK for Thread.join() if we are in the main thread.
# In that case, a Thread.join(timeout=None) would hang and even not respond to signals
# because signals will get delivered to other threads and Python would forward
# them for delayed handling to the main thread which hangs.
# See CPython signalmodule.c.
# Currently the best solution I can think of:
while threadObj.isAlive():
join_orig(threadObj, timeout=0.1)
else:
# In all other cases, we can use the original.
join_orig(threadObj, timeout=timeout)
threading.Thread.join = join_hacked
答案 4 :(得分:0)
将try ... except
放在每个帖子中,并将signal.pause()
放在 true main()
中。
留意{ {3}}但是。我猜这就是Python默认不解决ctrl-C的原因。