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()