相关疑难解决方法(0)

线程忽略KeyboardInterrupt异常

我正在运行这个简单的代码:

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')
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,它会打印出来

$ python prova.py
.
.
^C.
.
.
.
.
.
.
.
Exception KeyboardInterrupt in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored
Run Code Online (Sandbox Code Playgroud)

实际上python线程忽略我的Ctrl+ C键盘中断而不打印Received Keyboard Interrupt.为什么?这段代码有什么问题?

python events multithreading exception keyboardinterrupt

48
推荐指数
3
解决办法
5万
查看次数

使用^ C/KeyboardInterrupt在子线程中中断Python raw_input()

在多线程Python程序中,一个线程有时会使用内置的raw_input()来请求控制台输入.我希望能够在raw_input提示符下通过在shell中键入^ C来关闭程序(即,使用SIGINT信号).但是,当子线程正在执行raw_input时,键入^ C什么也不做 - 在我点击返回(离开raw_input)之前不会引发KeyboardInterrupt.

例如,在以下程序中:

import threading

class T(threading.Thread):
    def run(self):
        x = raw_input()
        print x

if __name__ == '__main__':
    t = T()
    t.start()
    t.join()
Run Code Online (Sandbox Code Playgroud)

键入^ C在输入完成之前不会执行任何操作.但是,如果我们只是调用T().run()(即,单线程情况:只在主线程中运行raw_input),^ C立即关闭程序.

据推测,这是因为SIGINT被发送到主线程,它被挂起(等待GIL),而分支线程在控制台上阻塞读取.主线程在raw_input返回后抓取GIL之前不会执行其信号处理程序.(如果我错了,请纠正我 - 我不是Python线程实现方面的专家.)

有没有办法以类似raw_input的方式从stdin读取,同时允许主线程处理SIGINT,从而降低整个过程?

[我在Mac OS X和一些不同的Linux上观察到了上述行为.]


编辑:我错误地描述了上面的根本问题.在进一步调查中,主要线程的呼吁join()是阻止信号处理:Guido van Rossum本人已经解释说,加入的底层锁定是不可中断的.这意味着信号实际上被推迟到整个线程完成 - 所以这实际上完全没有任何关系raw_input(只是后台线程阻塞以便连接没有完成的事实).

python input sigint control-c python-multithreading

8
推荐指数
2
解决办法
2466
查看次数