繁体   English   中英

Python:每n秒运行一次代码并在条件下重启计时器

[英]Python: Run code every n seconds and restart timer on condition

这可能比我想象的要简单,但我想创建一个计时器,当达到一个限制(比如15分钟)时,会执行一些代码。

与此同时,我想测试一下情况。 如果满足条件,则重置计时器并再次开始处理,否则倒计时继续。

如果在倒计时结束后满足条件,则执行一些代码并且计时器再次开始倒计时。

这是否涉及threading或是否可以通过简单的time.sleep()函数实现?

如果整个过程就像你说的一样简单,我会像这样(半伪代码):

def run_every_fifteen_minutes():
  pass
def should_reset_timer():
  pass
def main():
  timer = 0
  while True:
    time.sleep(1)
    timer+=1
    if should_reset_timer():
      timer = 0
    if timer == 15*60:
      run_every_fifteen_minutes()
      timer = 0

请注意,这不会是十五分钟。它可能会延迟几秒钟。 睡眠不保证只能睡1秒,其余的循环也需要一些时间。 如果你需要它真正准确的话,你可以在那里添加一个系统时间比较。

您可以通过线程优雅地实现它,但如果您需要快速修复,您可以尝试

import time
timer = 15 * 60 # 60 seconds times 15 mins
while timer > 0:
    time.sleep(0.985) # don't sleep for a full second or else you'll be off
    timer -= 1
    if someCondition:
          timer = 15 * 60
executeCode() # called when time is zero and while loop is exited

感谢大家的帮助,您的回答指出了我正确的方向。 最后我提出了:

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import subprocess

GPIO.setmode(GPIO.BCM)
PIR_PIN = 4
GPIO.setup(PIR_PIN, GPIO.IN)
timer = 15 * 60 # 60 seconds times 15 mins

subprocess.call("sudo /opt/vc/bin/tvservice -o", shell=True)

try :
    print "Screen Timer (CTRL+C to exit)"
    time.sleep(5)
    print "Ready..."

    while True:
        time.sleep(0.985)

        # Test PIR_PIN condition
        current_state = GPIO.input(PIR_PIN)

        if timer > 0:
            timer -= 1

            if current_state: #is true
                # Reset timer
                timer = 15 * 60

        else:
            if current_state: #is true
                subprocess.call("sudo /opt/vc/bin/tvservice -p", shell=True)

                # Reset timer
                timer = 15 * 60
            else:
                subprocess.call("sudo /opt/vc/bin/tvservice -o", shell=True)

except KeyboardInterrupt:
    print "Quit"
    GPIO.cleanup()

为了说明问题,我正在使用PIR传感器检测运动并在Raspberry Pi上打开hdmi连接的监视器。 在没有移动15分钟后,我想关闭显示器,然后如果(稍后)检测到移动,再次将其重新打开并重新开始计时。

描述听起来类似于死主的开关 / 看门狗定时器 它的实现方式取决于您的应用程序:是否存在事件循环,是否存在阻塞函数,是否需要单独的进程以进行正确的隔离等。如果代码中没有阻塞函数:

#!/usr/bin/env python3
import time
from time import time as timer

timeout = 900 # 15 minutes in seconds
countdown = timeout # reset the count
while True:
    time.sleep(1 - timer() % 1) # lock with the timer, to avoid drift
    countdown -= 1
    if should_reset_count():
        countdown = timeout # reset the count
    if countdown <= 0: # timeout happened
        countdown = timeout # reset the count
        "some code is executed"

该代码假定睡眠永远不会中断(注意:在Python 3.5之前,睡眠可能会被信号中断)。 该代码还假设没有任何功能需要很长时间(大约一秒钟)。 否则,您应该使用明确的截止日期(相同的代码结构):

deadline = timer() + timeout # reset
while True:
    time.sleep(1 - timer() % 1) # lock with the timer, to avoid drift
    if should_reset_count():
        deadline = timer() + timeout # reset
    if deadline < timer(): # timeout
        deadline = timer() + timeout # reset
        "some code is executed"

也许您应该查看Linux工具cron来安排脚本的执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM