我在Python中管理无限while循环时遇到问题,在该循环中我将插入计时器作为一种"看门狗"。我试图更好地解释一下:脚本必须侦听串行通道,并等待来自通道另一侧连接的传感器的消息。
我使用一会儿True循环来执行此操作,因为脚本必须捕获所有正在传递的信号。但是,即使可能不必要,我也想插入一个始终在每个循环中重置的计时器。因此,如果(例如)由于某种原因导致循环卡住,计时器将结束并退出程序。我以为我可以这样:
1
2
3
4
5
6def periodicUpdate():
exitTimer = threading.Timer(60.0, sys.exit())
while True:
exitTimer.start()
readData()
exitTimer.cancel()
现在的问题是,当我启动脚本时,它会立即退出。似乎它在所有其余部分之前都读取了sys.exit(),并且它不尊重计时器的构造,而只是在调用periodUpdate时它退出了。为什么会这样?我尝试更改语法,将sys.exit放在另一个函数中并调用该函数,我尝试了其他解决方案,但始终以两种方式运行:退出或由于不存在计时器而运行。有人能帮我吗?非常感谢
我认为您的方法不是最好的方法,而不是运行退出应用程序的计时器,为什么不简单地使读取数据的函数超时:
函数调用超时
虐待尝试您的方法,生病会让您知道!谢谢!
删除括号。如果使用sys.exit(),它将立即启动。使用sys.exit时,它将作为Timer的第二个参数传递该函数。
与上述相同:)感谢您的回答。但是没有括号,脚本只是表现为计时器不存在。它不会退出。它继续迭代!
It seems that it reads sys.exit() before all the rest
当然可以。 threadint.Timer的第二个参数是将被调用的函数。您要做的是实际上调用sys.exit并将其返回值(顺便说一句,因为该调用终止了程序,因此未定义)作为要调用的函数。这是一个错误,因为sys.exit的返回值不是函数,但这无关紧要,因为无论如何该程序都将终止。
你想做的是
1exitTimer = threading.Timer(60.0, sys.exit) # note: no brackets
但这实际上不起作用,因为线程中的sys.exit将仅终止该线程。简而言之,如果主循环中存在循环while,则不能使用看门狗终止该循环。在您的特定情况下,您应该研究用于读取数据的功能,很可能它可以让您设置读取超时。
感谢您的回答。我试过了,就像您说的那样,但没有括号,脚本会简单地表现为计时器不存在。它不会退出。它继续迭代!
@SaiT哦,可以肯定,sys.exit在线程中不起作用,我完全忘记了它。病态更新我的答案。
感谢您的更新:)生病尝试调查,然后我将再次更新您
在我看来,这里提出的解决方案都没有真正起作用。这是一个代码示例。很高兴知道如何解决它。另外,请在回答之前尝试一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import 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()
实际输出为:
1
2
3
4$python test.py
go
exiting
RuntimeError: threads can only be started once
1threading.Timer(60.0, os._exit, [0])
在计时器调用中从sys.exit中删除()
1
2
3
4
5
6
7
8
9def _exit()
sys.exit()
def periodicUpdate():
exitTimer = threading.Timer(60.0, _exit)
while True:
exitTimer.start()
readData()
exitTimer.cancel()
在您输入()时,解释器将调用此函数,否则解释器将获得此函数的引用。
玩得开心 :)
编辑:使用_exit
嗨,谢谢你的帮助!问题是,如果我删除括号,该脚本的行为就像计时器不存在一样。它没有退出...
然后使用我要编辑响应的功能。
尝试时我得到:RuntimeError:线程只能启动一次。您可能需要在每个循环中创建一个新计时器吗?
老实说,我没有任何错误!我的计时器根本不启动:D循环继续迭代...:S
1exitTimer = threading.Timer(60.0, sys.exit)
1
2
3
4
5
6
7
8
9def periodicUpdate():
exitTimer = sys.exit(60.0, sys.exit())
while sys.exit():
sys.exit()
readData()
sys.exit()
if __name__ =="__main__":
sys.exit()
不要忘记导入sys。
没有没有系统导入!
那么,这似乎是一个很好的程序。祝好运!