如何防止Python中的KeyboardInterrupt中断代码块?

问题描述 投票:46回答:5

我正在编写一个程序,通过pickle模块缓存一些结果。目前发生的事情是,如果我在发生dump操作时点击ctrl-c,dump会被中断并且生成的文件被破坏(即只是部分写入,所以它不能再次进行loaded。

有没有办法让qazxsw poi,或者一般的代码块,不间断?我目前的解决方法看起来像这样:

dump

如果它被中断,重启操作似乎很愚蠢,所以我正在寻找一种推迟中断的方法。我该怎么做呢?

python
5个回答
37
投票

将函数放在一个线程中,等待线程完成。

除了特殊的C api之外,不能中断Python线程。

try:
  file = open(path, 'w')
  dump(obj, file)
  file.close()
except KeyboardInterrupt:
  file.close()
  file.open(path,'w')
  dump(obj, file)
  file.close()
  raise

看看在线程完成之前中断是如何推迟的?

在这里它适合您的使用:

import time
from threading import Thread

def noInterrupt():
    for i in xrange(4):
        print i
        time.sleep(1)

a = Thread(target=noInterrupt)
a.start()
a.join()
print "done"


0
1
2
3
Traceback (most recent call last):
  File "C:\Users\Admin\Desktop\test.py", line 11, in <module>
    a.join()
  File "C:\Python26\lib\threading.py", line 634, in join
    self.__block.wait()
  File "C:\Python26\lib\threading.py", line 237, in wait
    waiter.acquire()
KeyboardInterrupt

59
投票

以下是为import time from threading import Thread def noInterrupt(path, obj): try: file = open(path, 'w') dump(obj, file) finally: file.close() a = Thread(target=noInterrupt, args=(path,obj)) a.start() a.join() 附加信号处理程序的上下文管理器。如果调用上下文管理器的信号处理程序,则在上下文管理器退出时仅通过将信号传递给原始处理程序来延迟信号。

SIGINT

25
投票

使用import signal import logging class DelayedKeyboardInterrupt(object): def __enter__(self): self.signal_received = False self.old_handler = signal.signal(signal.SIGINT, self.handler) def handler(self, sig, frame): self.signal_received = (sig, frame) logging.debug('SIGINT received. Delaying KeyboardInterrupt.') def __exit__(self, type, value, traceback): signal.signal(signal.SIGINT, self.old_handler) if self.signal_received: self.old_handler(*self.signal_received) with DelayedKeyboardInterrupt(): # stuff here will not be interrupted by SIGINT critical_code() 模块在进程持续时间内禁用SIGINT:

signal

10
投票

在我看来,使用线程是一种矫枉过正。您只需在循环中执行此操作即可确保正确保存文件,直到成功完成写入为止:

s = signal.signal(signal.SIGINT, signal.SIG_IGN)
do_important_stuff()
signal.signal(signal.SIGINT, s)

1
投票

这个问题是关于阻止def saveToFile(obj, filename): file = open(filename, 'w') cPickle.dump(obj, file) file.close() return True done = False while not done: try: done = saveToFile(obj, 'file') except KeyboardInterrupt: print 'retry' continue ,但对于这种情况,我发现原子文件写作更清洁,并提供额外的保护。

使用原子写入可以正确写入整个文件,也可以不做任何事情。 Stackoverflow有一个KeyboardInterrupt,但我个人喜欢使用variety of solutions库。

运行atomicwrites后,只需使用它:

pip install atomicwrites
© www.soinside.com 2019 - 2024. All rights reserved.