0

我在管理 Python 中的无限 while 循环时遇到问题,我将在其中插入一个计时器作为一种“看门狗”。我试图更好地解释:脚本必须在串行通道上侦听并等待来自连接在通道另一侧的传感器的消息。我使用 while True 循环来执行此操作,因为脚本必须捕获所有正在传递的信号。然而,即使它可能是不必要的,我想插入一个计时器,它总是在每个循环中重置。因此,如果(例如)循环由于某种原因卡住,计时器将结束并退出程序。我以为我可以这样做:

def periodicUpdate():
    exitTimer = threading.Timer(60.0, sys.exit())
    while True:
        exitTimer.start()
        readData()
        exitTimer.cancel()

现在,问题是当我启动脚本时它立即退出。似乎它sys.exit()在所有其他内容之前读取,并且它不尊重计时器的构造,而只是在调用periodicUpdate 时它退出。为什么会这样?!我尝试更改语法,将 sys.exit 放在另一个函数中并调用该函数,我尝试了其他解决方案,但它总是以两种方式表现:它退出或表现为计时器不存在。有人能帮我吗?非常感谢

4

8 回答 8

2

似乎它sys.exit()在所有其他内容之前阅读

当然可以。的第二个参数threadint.Timer是一个将被调用的函数。您所做的是实际调用 sys.exit并提供其返回值(顺便说一句,这是未定义的,因为调用终止了程序)作为要调用的函数。这是一个错误,因为sys.exit' 的返回值不是函数,但这并不重要,因为程序无论如何都会终止。

你想做的是

exitTimer = threading.Timer(60.0, sys.exit) # note: no brackets

但这实际上是行不通的,因为sys.exit在线程中只会终止那个线程。简而言之,while如果这个循环在你的主线程中,你不能使用看门狗来终止一个卡住的循环。在您的特定情况下,您应该研究用于读取数据的函数,很可能它可以让您设置读取超时。

于 2013-06-07T09:27:39.833 回答
2

删除括号。如果你使用sys.exit(),它会立即开火。当您使用sys.exit时,它会将函数作为Timer的第二个参数传递。

于 2013-06-07T09:27:40.130 回答
2

我认为您的方法不是最好的方法,而不是运行退出应用程序的计时器,为什么不简单地使读取数据的函数超时:

函数调用超时

于 2013-06-07T09:45:08.913 回答
1

在我看来,这里提出的解决方案都没有真正奏效。这是一个代码示例。很高兴知道如何解决它。另外,请在回答之前尝试一下。

import time, threading, sys

def _exit():
    print 'exiting'
    sys.exit()

def periodicUpdate():
    exitTimer = threading.Timer(2.0, _exit)
    while True:
        exitTimer.start()
        print 'go'
        time.sleep(5)
        exitTimer.cancel()


periodicUpdate()

实际输出为:

$python test.py
go
exiting
RuntimeError: threads can only be started once
于 2013-06-07T11:20:28.247 回答
0

在计时器调用中从 sys.exit 中删除 ()

def _exit()
    sys.exit()

def periodicUpdate():
    exitTimer = threading.Timer(60.0, _exit)
    while True:
        exitTimer.start()
        readData()
        exitTimer.cancel()

在你把 () 解释器调用这个函数,如果不是解释器得到这个函数的引用。

玩得开心 :)

编辑:使用 _exit

于 2013-06-07T09:32:25.773 回答
0
exitTimer = threading.Timer(60.0, sys.exit)
于 2013-06-07T09:29:09.700 回答
0
threading.Timer(60.0, os._exit, [0])
于 2013-06-07T09:49:15.737 回答
-2
def periodicUpdate():
    exitTimer = sys.exit(60.0, sys.exit())
    while sys.exit():
        sys.exit()
        readData()
        sys.exit()

if __name__ == "__main__":
    sys.exit()

不要忘记导入 sys.

于 2013-06-07T09:35:39.050 回答