是否可以防止python终止直到块结束?

时间:2019-05-20 16:30:20

标签: python python-3.x signals atomic

基本上,我很好奇能否在不被信号中断的情况下“原子地”执行python代码块。

例如,我想循环执行操作,比如说:

for i in range(100):
    do_stuff(1)
    do_stuff(2)
    do_stuff(3)

但是,如果do_stuff(1) 可以开始,我想完成三个do_stuff(2)do_stuff(3)do_stuff(1)的全部操作。脚本应忽略CTRL + C,完成这三个指令,然后在发生SIGINT时终止。不必全部执行100次迭代。

我相信可以通过自定义信号处理程序完成

import signal

def handler(signum, frame):
    # wait for the loop iteration finish and exit
signal.signal(signal.SIGINT, handler)

线程和同步,但是我不知道如何实现。

  1. 有可能吗?
  2. 如果是,可以做得很好吗?例如,使用某种上下文管理器?
for i in range(100):
    with atomic_execution():
        do_stuff(1)
        do_stuff(2)
        do_stuff(3)

编辑:同时我创建了这个

import threading
import sys
import signal


class atomic_execution:
    started = 0
    execution_in_progress = threading.Lock()

    def __enter__(self):
        atomic_execution.execution_in_progress.acquire()

    def __exit__(self, type, value, traceback):
        atomic_execution.execution_in_progress.release()


def handler(signum, frame):
  atomic_execution.execution_in_progress.acquire()
  sys.exit(0)

signal.signal(signal.SIGINT, handler)

while True:
  with atomic_execution():
    print(1)
    print(2)
    print(3)

不过,我不确定是否很好。

1 个答案:

答案 0 :(得分:1)

这是基本概念:

import signal
import time

stop = False

def sighandler(*unused):
    global stop
    print('signal caught')
    stop = True

def main():
    for i in range(10):
        print('a')
        time.sleep(0.5)
        print('b')
        time.sleep(0.5)
        print('c')
        time.sleep(0.5)
        print()
        if stop:
            print('STOP')
            break

if __name__ == '__main__':
    signal.signal(signal.SIGINT, sighandler)
    main()

我认为为此目的而创建上下文管理器并不困难:

在输入:

  • 保存当前信号处理程序
  • 安装自己的处理程序,像上面的示例一样设置标志

退出时:

  • 还原原始信号处理程序
  • 如果已设置标志则退出

但是我不喜欢这个主意,因为您想在循环之前安装一次处理程序,并在每次迭代中多次测试该标志。