python - 无法捕获线程程序中的异常

标签 python multithreading unix exception python-2.x

下面的Python程序启动一个线程,然后继续在主线程中执行操作。我将整个主线程包装在一个 try-except block 中,这样如果发生异常,我可以拆除所有正在运行的线程。

当我使用 Python 2.7.5 运行脚本并在程序执行期间的随机点调用 KeyboardInterrupt 时,会触发异常但未捕获异常。程序继续运行。

$ python test.py 
Running server ...
Searching for servers ...
^CTraceback (most recent call last):
  File "test.py", line 50, in <module>
    main()
  File "test.py", line 40, in main
    app_main()
  File "test.py", line 35, in app_main
    searchservers()
  File "test.py", line 26, in searchservers
    time.sleep(0.0005)
KeyboardInterrupt

我错过了发生异常时在 main() 中打印的输出中的一行。


代码

import time
import threading

thread_pool = []
running = False

def stop():
    global running
    running = False

def runserver():
    print "Running server ..."

    global running
    running = True

    while running:
        time.sleep(0.07)

def searchservers():
    print "Searching for servers ..."

    for i in xrange(256):
        for j in xrange(256):
            time.sleep(0.0005)

def app_main():
    server = threading.Thread(target=runserver)
    thread_pool.append(server)
    server.start()

    time.sleep(0.1)

    searchservers()
    stop()

def main():
    try:
        app_main()
    except Exception as exc:
        stop()
        print "%s occured, joining all threads..." % exc.__class__.__name__
        for thread in thread_pool:
            thread.join()

        raise exc

if __name__ == "__main__":
    main()

为什么键盘中断没有被捕获?在线程程序中捕获异常并拆除整个过程的正确方法是什么?

最佳答案

KeyboardInterrupt 是一个特殊异常;与 MemoryErrorGeneratorExitSystemExit 一样,它不是派生自基本 Exception类。

因此,仅捕获异常是不够的;你通常会明确地捕捉到它:

except (Exception, KeyboardInterrupt) as exc:

但是,您还 try catch 线程中的异常;线程有自己独立的堆栈;你不能只是去捕获主线程中那些堆栈中抛出的异常。您必须捕获该线程中的异常:

def runserver():
    print "Running server ..."

    global running
    running = True

    try:    
        while running:
            time.sleep(0.07)
    except (Exception, KeyboardInterrupt) as exc:
        print "Error in the runserver thread"

要以通用方式处理此问题并将异常“传递”到主线程,您需要某种线程间通信。请参阅Catch a thread's exception in the caller thread in Python以获得完整的解决方案。

关于python - 无法捕获线程程序中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19604943/

相关文章:

python - Genfromtxt 抛出异常 "got 3 columns instead of 27"但事实并非如此

c - 在 C 中使用线程的异步文件 I/O

linux - 列出所有文件并找到特定文件位置

用于多行匹配的Python正则表达式命名组

python - 将 ctypes 指针转换为 float 的 numpy 数组

java - 如何仅在另一个方法完成后才执行该方法?

multithreading - 在python3中的多进程之间共享python对象

c - 为什么 struct stat 中的 st_size 字段是有符号的?

linux - 通过管道发送到 Grep 会给出太多结果

python - 尝试在 python 中实现子集总和解决方案的问题