超时和异常功能被卡住



我正在使用python 2.7.10功能进行轮询数据,如果设备花费太长响应时间太长,或者如果该设备不可用,请捕获RuntimeError。我正在使用此超时功能:

class Timeout():
        class Timeout(Exception):
            pass
        def __init__(self, sec):
            self.sec = sec
        def __enter__(self):
            signal.signal(signal.SIGALRM, self.raise_timeout)
            signal.alarm(self.sec)
        def __exit__(self, *args):
            signal.alarm(0)
        def raise_timeout(self, *args):
            raise Timeout.Timeout()

这是我进行数据投票(Modbus)并捕获异常的循环。此循环每60秒称为一次:

def getDeviceTags(name, tag_data):
    global val_returns
    for tag in tag_data[name]:
        local_vals = []
        local_vals.append(name+"."+tag)
        try:
            with Timeout(3):
                value = modbus.read(str(name), str(tag))
                local_vals.append(str(value.value()))
        except RuntimeError:
            print("RuntimeError on " + str(name))
            local_vals.append(None)
        except Timeout.Timeout:
            print("Timeout on " + str(name))
            local_vals.append(None)
        val_returns.append(local_vals)

这将在没有问题的情况下一次工作几天,包括运行时间和超时打印到控制台上,所有数据已记录 - 很棒。但是,最近它被卡住了 - 这是我遇到的唯一错误:

Traceback (most recent call last):
  File "working_one_min_back.py", line 161, in <module>
    job()
  File "working_one_min_back.py", line 79, in job
    getDeviceTags(str(key), data)
  File "working_one_min_back.py", line 57, in getDeviceTags
    print("RuntimeError on " + str(name))
  File "working_one_min_back.py", line 30, in raise_timeout
    raise Timeout.Timeout()
__main__.Timeout

不能保证在访问 alarm(0)之后不会传递" python信号"。实际(c)信号可能已经交付了,导致python处理程序稍后调用一些字体模式指令。

如果您从__exit__调用signal.signal,则任何此类待处理信号都是丢弃的,它会有效防止将其误以为 next 一个请求。无论如何,将其用于还原在创建Timeout之前具有的处理程序(第一个signal.signal调用返回)还是一个好主意。(在调用alarm(0)以防止SIG_DFL杀死该过程。)

在python&nbsp; 3中,这样的调用传递任何待处理信号而不是丢弃它们,这是一个改进,因为它仅仅因为处理程序更改了信号而阻止丢失信号。(不幸的是,这没有比Python&nbsp; 2行为更有记录。)您可以尝试通过在__exit__中设置属性并忽略设置时引起的任何(python)信号来抑制这种后期信号。

> 。

当然,可以在__exit__开始执行和丢弃信号之前(或标记为被忽略)后传递信号。因此,您必须处理操作完成和计时,也许是通过对单个变量进行几个分配,然后仅在一个地方进行 append ed。

最新更新