Python 每n秒运行一次特定代码

Python 每n秒运行一次特定代码,python,multithreading,Python,Multithreading,例如,有没有办法打印Hello World每n秒? 例如,程序将遍历我所有的代码,然后在5秒后(使用time.sleep())它将执行该代码。我会用它来更新一个文件,而不是打印Hello World 例如: startrepeat("print('Hello World')", .01) # Repeats print('Hello World') ever .01 seconds for i in range(5): print(i) >> Hello World! &

例如,有没有办法打印
Hello World每n秒?
例如,程序将遍历我所有的代码,然后在5秒后(使用
time.sleep()
)它将执行该代码。我会用它来更新一个文件,而不是打印Hello World

例如:

startrepeat("print('Hello World')", .01) # Repeats print('Hello World') ever .01 seconds

for i in range(5):
    print(i)

>> Hello World!
>> 0
>> 1
>> 2
>> Hello World!
>> 3
>> Hello World!
>> 4

它将作为函数运行。
while True:
使其永远运行。如果需要,您可以随时将其从函数中取出。

您可以启动一个单独的线程,该线程的唯一任务是计数5秒,更新文件,然后重复。您不希望这个单独的线程干扰主线程

import threading

def printit():
  threading.Timer(5.0, printit).start()
  print "Hello, World!"

printit()

# continue with the rest of your code

我对这个主题的拙见,是Alex Martelli答案的概括,带有start()和stop()控件:

用法:

from time import sleep

def hello(name):
    print "Hello %s!" % name

print "starting..."
rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start()
try:
    sleep(5) # your long-running job goes here...
finally:
    rt.stop() # better in a try/finally block to make sure the program ends!
特点:

  • 仅标准库,无外部依赖项
  • start()
    stop()
    可以安全地多次调用,即使计时器已经启动/停止
  • 要调用的函数可以具有位置参数和命名参数
  • 您可以随时更改
    间隔
    ,它将在下次运行后生效。对于
    args
    kwargs
    甚至
    函数也一样
    
保存一段精神分裂症插曲,并使用高级Python调度程序:

代码非常简单:

from apscheduler.scheduler import Scheduler

sched = Scheduler()
sched.start()

def some_job():
    print "Every 10 seconds"

sched.add_interval_job(some_job, seconds = 10)

....
sched.shutdown()

这是一个不会每隔
n
秒创建一个新线程的版本:

from threading import Event, Thread

def call_repeatedly(interval, func, *args):
    stopped = Event()
    def loop():
        while not stopped.wait(interval): # the first call is in `interval` secs
            func(*args)
    Thread(target=loop).start()    
    return stopped.set
该事件用于停止重复:

cancel_future_calls = call_repeatedly(5, print, "Hello, World")
# do something else here...
cancel_future_calls() # stop future calls

参见

以下是一个与以下内容兼容的简单示例:

或者,您可以使用以下命令。与许多备选方案不同,此计时器将每n秒执行一次所需代码(与代码执行所需的时间无关)。因此,如果你不能承受任何漂移,这是一个很好的选择

import time
from threading import Event, Thread

class RepeatedTimer:

    """Repeat `function` every `interval` seconds."""

    def __init__(self, interval, function, *args, **kwargs):
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.start = time.time()
        self.event = Event()
        self.thread = Thread(target=self._target)
        self.thread.start()

    def _target(self):
        while not self.event.wait(self._time):
            self.function(*self.args, **self.kwargs)

    @property
    def _time(self):
        return self.interval - ((time.time() - self.start) % self.interval)

    def stop(self):
        self.event.set()
        self.thread.join()


# start timer
timer = RepeatedTimer(10, print, 'Hello world')

# stop timer
timer.stop()


不起作用;它永远在运行,我不能在它运行的同时做任何其他事情。你还想同时做什么其他事情?好吧,这只是一个循环。您在问题中没有指定在此期间您将执行其他操作,因此我假设这是您需要的。注意:这不会每5秒运行一次。它将每隔
5+N
秒运行一次,其中
N
是执行
之间的时间,而True:
时间。睡眠(5)
。而这对于
打印“Hellow World!”是微不足道的与5整秒相比,对于其他场景来说,这可能是不平凡的。我应该注意的是,使用线程也不会精确到5秒,但会更近。我知道我可能晚了9年,但这不是一个有效的解决方案,他特别说,
…程序将通过我拥有的任何代码,然后一旦达到5秒…
。好的,修复,请注意,您可能还希望将由
Timer
生成的线程设置为
daemon
,以防您只需完成主线程即可完全中断程序——在这种情况下,您最好设置
t=threading.Timer
&c,然后设置
t.daemon=True
,然后设置
t.start()
就在打印“你好,世界!”
之前。这似乎根本解决不了问题。。。它不会每秒钟重复一次。@YanKingYin:试着运行它。它确实在重复
printit
schedulers本身。这不会最终达到递归函数的限制吗?如何停止它?首先,子模块称为“schedulers”,带有“s”。而且里面没有类调度程序。也许是背景?无论如何,这个答案是不完整的,不起作用。已经有一段时间了,我想我粘贴了web用户手册中的代码。上面的代码现在已经更正(仍然没有测试,但它来自我自己的工作代码,我一直在使用它)。PS:也许我们在看不同的版本/模块?我确信我的行是“from apscheduler.scheduler import scheduler”,大写字母S,不是复数。@MadsSkjern:我明白了。目前的分支3没有。现在(2014年11月)看到这个答案的任何人都应该知道,这虽然是一个好答案,但都是错的。上述评论对此进行了讨论。要在当前版本中添加作业,代码将读取
sched.add\u job(某些作业,'interval',seconds=10)
。查看相关的:@JossieCalderon:
sleep()
函数位于Python标准库中的
time
模块中,除了导入
之外,不需要任何其他代码来使用它。但请注意,这是一个一次性阻塞调用,而不是OP请求的重复多线程计时器。基本上,
sleep()
只是一个暂停,而不是一个计时器。这很好,但请注意,它不会每n秒运行一次作业。相反,它运行一个n秒计时器,然后快速启动另一个n秒计时器。。。但是在下一个计时器启动之前有一个延迟。所以它并不是每n秒发射一次;相反,它会漂移,两个作业之间的间隔时间略大于n秒。运行作业打印当前时间的1秒计时器产生:开始。。。16:07:42.017682 16:07:43.023215 16:07:44.023626等。是的,@eraoul,它确实会漂移,因为没有直接的方法使用Python的标准库设置真正的循环计时器,所以我“链接”了几个一次性计时器来模拟它。然而,第一次运行的漂移为5毫秒,第二次运行的漂移为0.4毫秒,因此大约需要200到2500次运行才能漂移一整秒钟,这可能对您来说很重要,也可能不重要。为了在数千次运行中获得更高的准确性,可以根据RTC计算下一次运行,或者使用外部工具,如
cron
谢谢。我添加了
self.\u timer.daemon=True
以更好地处理关机,并将函数调用移到
self.\u timer.start()
之后立即运行。@Sarthak:停止你说的计时器?您可以向被调用的函数添加一些逻辑来检查经过的时间(将当前时间与以前保存的全局时间进行比较)
cancel_future_calls = call_repeatedly(5, print, "Hello, World")
# do something else here...
cancel_future_calls() # stop future calls
# note that there are many other schedulers available
from apscheduler.schedulers.background import BackgroundScheduler

sched = BackgroundScheduler()

def some_job():
    print('Every 10 seconds')

# seconds can be replaced with minutes, hours, or days
sched.add_job(some_job, 'interval', seconds=10)
sched.start()

...

sched.shutdown()
import time
from threading import Event, Thread

class RepeatedTimer:

    """Repeat `function` every `interval` seconds."""

    def __init__(self, interval, function, *args, **kwargs):
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.start = time.time()
        self.event = Event()
        self.thread = Thread(target=self._target)
        self.thread.start()

    def _target(self):
        while not self.event.wait(self._time):
            self.function(*self.args, **self.kwargs)

    @property
    def _time(self):
        return self.interval - ((time.time() - self.start) % self.interval)

    def stop(self):
        self.event.set()
        self.thread.join()


# start timer
timer = RepeatedTimer(10, print, 'Hello world')

# stop timer
timer.stop()