gpt4 book ai didi

python - 无限循环中不触发警报信号

转载 作者:太空宇宙 更新时间:2023-11-04 03:41:30 25 4
gpt4 key购买 nike

如果某个函数运行超过 3 秒(例如),我会尝试使该函数超时。我正在使用信号和警报,但警报从未触发。我想要一个适用于任何功能的超时机制。作为我面临的问题的一个例子:

import signal

def foobar():
x = 42
while x >= 20:
if x >= 40:
x = 23
return x

def handle_alarm(*args):
print("Alarm raised")
raise TimeoutException("timeout reached")

signal.signal(signal.SIGALRM, handle_alarm)
signal.alarm(3)

try:
print(foobar())
except:
print("Exception Caught")

运行时,我的程序会永远运行,而我的处理程序永远不会运行。知道为什么会这样吗?

顺便说一句,如果我从 foobar 中删除 if 语句,那么警报就会触发。

最佳答案

在我的系统 Mac OS X 和 MacPorts 上,我用许多版本的 Python 测试了你的代码。唯一显示您发现的“错误”的版本是 2.7。超时适用于 2.4、2.5、2.6、3.3 和 3.4。

现在,为什么会发生这种情况,可以采取什么措施?

我认为这是因为您的 foobar()是一个紧密的循环,它永远不会“让步”控制回到 Python 的主循环。它只是尽可能快地运行,不做任何有用的工作,但阻止 Python 处理信号。

这将有助于理解 *nix 中的信号通常是如何处理的。由于很少有库函数是“异步信号安全的”,因此在 C 信号处理程序中不能直接完成很多工作。 Python 需要调用用 Python 编写的信号处理程序,但它不能直接在它使用 C 注册的信号处理程序中执行此操作。因此,程序在其信号处理程序中所做的典型事情是设置一些标志来指示收到一个信号,然后返回。然后,在主循环中,检查该标志(直接或通过使用可以写入信号处理程序和 poll() 编辑或 select() 编辑的“管道”)。

所以我假设 Python 主循环正在愉快地执行你的 foobar()函数,并且有一个信号进来,它设置一些内部状态来知道它需要处理那个信号,然后它等待foobar()。结束或失败,至少对于foobar()调用一些可中断函数,例如 sleep()print() .

事实上,如果您添加 sleep (任意时间)或 print声明 foobar()的循环,您将在 Python 2.7(以及其他版本)中获得所需的超时时间。

总的来说,在繁忙的循环中短暂休眠是个好主意,以“放松”它们,从而帮助安排可能需要做的其他工作。您也不必在每次迭代时都休眠——在这种情况下,每 1000 次循环只休眠一次就可以了。

关于python - 无限循环中不触发警报信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26199526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com