Python中的外部异常可以在代码块的持续时间内延迟吗?

时间:2014-06-13 18:51:55

标签: python multithreading python-2.7 exception-handling

有没有办法在特定代码块的持续时间内推迟来自外部源的异常?例如:

some_statement_one
some_statement_two
# Begin suppression of KeyboardInterrupt
with KeyboardInterrupt suppressing context:
    important_statement_one
    important_statement_two
    important_statement_three

some_statement_three

我希望能够做的是延迟接收KeyboardInterrupt(或我指定的任何错误),直到重要块结束之后。也就是说,如果在执行important_statement_one期间用户发送键盘中断,代码将继续正常直到它完成important_statement_three之后。然后,将收到KeyboardInterrupt,就好像它已经被发送一样。

我关心的只是在正在执行的代码外部生成的异常,例如KeyboardInterrupts,SystemExits等。是否有一种有意义的方法来区分正在执行的代码引发的异常和异常由于外在的东西而被提升?除非有,否则我可能无法做我想做的事。

其他一些信息: 我正在使用Is there any way to kill a Thread in Python?中建议的技术向线程发送异常。提出这样的例外是否会产生影响?

我不能真正使用try / except块 - 我是线程之间的一些信息,所以如果在传递信息的行上发送异常,则信息将丢失。

2 个答案:

答案 0 :(得分:2)

我认为你想要覆盖sigint信号的默认处理程序。

这是一种简单的方法。

some_statement_one
some_statement_two

# Save sigint handler
original_sigint_handler = signal.getsignal(signal.SIGINT)

# Set sigint handler to a function that does nothing with it
signal.signal(signal.SIGINT, lambda: None)

important_statement_one
important_statement_two
important_statement_three

# Restore handler
signal.signal(signal.SIGINT, original_sigint_handler)

some_statement_three

您可能希望将其包装在一个类中,并使用enter和exit函数来获得更清晰的代码。 您的代码看起来就像您想要的那样(使用"使用")

阅读:Explaining Python's '__enter__' and '__exit__'

答案 1 :(得分:0)

请注意,这并不完全回答我的问题,但这专门用于推迟键盘中断。


根据Martijn Pieters的建议,信号处理程序可以用来处理键盘中断,然后才能成为需要捕获的异常:

import signal
import threading

interruptLock = threading.Lock()

def handleInterrupt(signum, frame):
    with interruptLock:
        raise KeyboardInterrupt()

signal.signal(signal.SIGINT, handleInterrupt)

然后在重要的代码中:

some_statement_one
some_statement_two
with interruptLock:
    important_statement_one
    ...

这一次只允许重要部分中的一个线程,但它会在中断锁定被释放之前推迟异常,因此在该部分期间不应该中断它。

如果您希望一次有多个线程通过重要部分,则可能需要使用读写器锁。读写器锁的一种实现可以是found here