终止python中的程序

时间:2016-03-31 03:30:54

标签: python popen terminate sys termination

您好我在我的python代码中嵌入了一个时间限制,该代码运行带有函数的fortran代码。但是我意识到将时间约束放在另一个函数上的函数并没有终止代码,只是将它留在后台并改为跳过它。我想要做的是在超过约束时间时终止代码。以下是我用来约束here时间的代码。

def timeout(func, args=(), kwargs={}, timeout_duration=15, default=1):
    import signal

    class TimeoutError(Exception):
        pass

    def handler(signum, frame):
        raise TimeoutError()

    # set the timeout handler                                                                                                                                             
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(timeout_duration)
    try:
        result = func(*args, **kwargs)
    except TimeoutError as exc:
        result = default
    finally:
        signal.alarm(0)

    return result

我查了popen.terminate()sys.exit()atexit.register(),但无法弄清楚它是如何处理这段代码的,我试图在下面添加一部分代码在评论中显示。

...
        result = func(*args, **kwargs)
    except TimeoutError as exc:
        result = default
#add the terminator
    finally:
...

注意:函数在for循环链中,所以我不想杀死整个python会话但只想杀死这个函数运行的程序,这是一个fortran代码并跳转到for循环链中的另一个元素。 / p>

以下部分经过一些评论和回答后添加:

我尝试使用popen.terminate()添加SIGTERM但是它终止了所有python会话,我只想终止当前运行的会话并跳转到for循环中的其他元素。我做的是如下:

...
    signal.signal(signal.SIGTERM, handler) 
    signal.alarm(timeout_duration)
    try:
        result = func(*args, **kwargs)
    except TimeoutError as exc:
        result = default
        popen.terminate()
...

1 个答案:

答案 0 :(得分:1)

您不能指望信号处理程序通过调用堆栈传播Exception,并在不同的上下文中调用它。

popen.terminate()会在posix系统上生成SIGTERM,因此您应该拥有SIGTERM而非SIGALRM的信号处理程序。

您应该设置一些定期检查以暂停活动的变量,而不是在信号处理程序中引发异常。

或者,如果您没有SIGTERM的信号处理程序,则默认处理程序可能会生成KeyboardInterrupt例外。