【问题标题】:Using a timer in a while true loop in Python在 Python 的 while true 循环中使用计时器
【发布时间】:2013-06-03 13:14:39
【问题描述】:

我在管理 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 放在另一个函数中并调用该函数,我尝试了其他解决方案,但它总是以两种方式表现:它退出或表现为计时器不存在。有人能帮我吗?非常感谢

【问题讨论】:

    标签: python python-2.7 timer while-loop exit


    【解决方案1】:

    去掉括号。如果您使用sys.exit(),它会立即触发。当您使用sys.exit 时,它会将函数作为Timer 的第二个参数传递。

    【讨论】:

    • 同上 :) 谢谢解答。但是如果没有括号,脚本的行为就像计时器不存在一样。它不退出。它继续迭代!
    【解决方案2】:

    我认为你的方法不是最好的,与其运行一个退出应用程序的计时器,为什么不简单地让读取数据的函数超时:

    Timeout on a function call

    【讨论】:

    • 我会试试你的方法,我会告诉你的!谢谢!
    【解决方案3】:

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

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

    你想做的是

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

    但这实际上不会起作用,就像线程 will terminate only that thread 中的 sys.exit 一样。简而言之,如果这个循环在你的主线程中,你不能使用看门狗来终止卡住的while-loop。在您的特定情况下,您应该调查您用于读取数据的函数,很可能它可以让您设置读取超时。

    【讨论】:

    • 感谢您的回答。我按照您所说的进行了尝试,但是没有括号,脚本的行为就像计时器不存在一样。它不退出。它继续迭代!
    • @SaiT 哦,当然,sys.exit 在线程中不起作用,我完全忘记了。我会更新我的答案。
    • 感谢您更新 :) 我会尝试调查,然后我会再次更新您
    【解决方案4】:

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

    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
    

    【讨论】:

      【解决方案5】:
      exitTimer = threading.Timer(60.0, sys.exit)
      

      【讨论】:

        【解决方案6】:

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

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

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

        玩得开心:)

        编辑:_exit 的使用

        【讨论】:

        • 您好,感谢您的帮助!问题是,如果我删除括号,脚本只是表现为计时器不存在。它没有退出...
        • 在尝试时我得到:RuntimeError:线程只能启动一次。您是否需要在每个循环中创建一个新计时器?
        • 老实说,我没有收到任何错误!我的计时器根本没有启动:D 循环继续迭代......:S
        【解决方案7】:
        threading.Timer(60.0, os._exit, [0])
        

        【讨论】:

          【解决方案8】:
          def periodicUpdate():
              exitTimer = sys.exit(60.0, sys.exit())
              while sys.exit():
                  sys.exit()
                  readData()
                  sys.exit()
          
          if __name__ == "__main__":
              sys.exit()
          

          别忘了导入 sys。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-23
            • 2020-07-03
            • 2017-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-01
            • 1970-01-01
            相关资源
            最近更新 更多