在 Python 中,为什么 `KeyboardInterrupt` 会阻止该对象的酸洗?

问题描述 投票:0回答:1

我需要更好的方法或者我需要学习如何使用该方法 我使用得比较正确。通常,当我按 cntrl-c 时 我的工作被腌制了,但有一次却没有。后来我尝试打开泡菜时,出现了

ran out of input
错误。我需要知道为什么会发生这种情况,以免再次发生。当我运行我的代码时,每一百个循环我都会保存pickle,如果我点击KeyboardInterrupt,理论上我的工作应该在程序停止之前被pickle。我的预感是,如果我在执行
KeyboardInterrupt
时按
pickle.dump(obj, temp)
那么该文件将覆盖旧文件,但由于它正在覆盖,如果程序在覆盖过程中被终止,那么该文件将被半写入。我也不明白的是,在我点击
KeyboardInterrupt
后,程序应该执行
print("help me")
行,但事实并非如此,至少在我尝试这样做的唯一一次。

import pickle

def save_pickle(obj, file):
    temp = open(file, "wb")
    ##i have a feeling that if i hit keyboard interrupt
    ##while the below line is being executed that it won't
    ## save the pickle properly
    pickle.dump(obj, temp)
    temp.close()

class help_me():
    def __init__(self):
        pass

    def func1(self):
        try:
            self.func2()
        except KeyboardInterrupt:
            pass
        print('help me')  # this line did not get activated
        save_pickle(obj, file)

    def func2(self):
        #this function will take several days
        for i in range(600_000):
            time.sleep(1)
            if i % 100 == 0:
                save_pickle(obj, file)
python pickle keyboardinterrupt
1个回答
0
投票

如评论中所述,如果您在将对象腌制到文件的过程中使用 SIGINT(即 CTRL+C)终止程序,则最终可能会得到部分写入(损坏)的文件。

为了避免这种情况,您可以自定义程序响应 SIGINT 的方式,以便关键部分不会突然停止。

在循环之前,为 SIGINT 注册一个临时 信号处理程序,设置“停止”标志而不是引发

KeyboardInterrupt
。在循环中,检查停止标志,并在设置后中断。循环结束后,您可以将信号处理程序重置为循环之前的状态。

def func2(self):
    stop = False
  
    def handle_sigint(_sig, _frame)
        nonlocal stop
        print("setting stop flag")
        stop = True

    original_handler = signal.getsignal(signal.SIGINT)
    signal.signal(signal.SIGINT, handle_sigint)

    while not stop:
        time.sleep(1)
        save_pickle(obj, file)

    signal.signal(signal.SIGINT, original_handler)
© www.soinside.com 2019 - 2024. All rights reserved.