定时器中断线程python

时间:2013-05-06 08:13:56

标签: python multithreading timer interrupt

我一直在尝试在python中制作精确的计时器,或者正如操作系统允许的那样精确。但它比我最初的想法更复杂。

这就是我希望它的工作方式:

from time import sleep
from threading import Timer

def do_this():
    print ("hello, world")


t = Timer(4, do_this)
t.start()
sleep(20)
t.cancel()

在20秒内,我会每隔四秒执行一次'do_this'。但是,“do_this”执行一次,然后脚本在20秒后终止。

另一种方法是使用while循环创建一个thred。

import time
import threading
import datetime

shutdown_event = threading.Event()

def dowork():
    while not shutdown_event.is_set():
        print(datetime.datetime.now())
        time.sleep(1.0)

def main():

    t = threading.Thread(target=dowork, args=(), name='worker')
    t.start()

    print("Instance started")

    try:
        while t.isAlive():
            t.join(timeout=1.0)
    except (KeyboardInterrupt, SystemExit):
            shutdown_event.set()
    pass

if __name__ == '__main__':
    main()

此线程按预期执行但我得到了时序漂移。在这种情况下,我必须通过相应地调整睡眠来补偿在while循环中执行代码所花费的时间。

python中是否有一种简单的方法可以每秒(或任何间隔)执行一个定时器,而不会在不必补偿sleep(n)参数的情况下与系统时间相比引入漂移?

感谢您的帮助,

/安德斯

1 个答案:

答案 0 :(得分:2)

如果dowork()总是以比你的间隔更短的时间运行,你可以在循环中每4秒产生一个新线程:

def dowork():
  wlen = random.random()
  sleep(wlen) # Emulate doing some work
  print 'work done in %0.2f seconds' % wlen

def main():
  while 1:
    t = threading.Thread(target=dowork)
    time.sleep(4)

如果dowork()可能运行超过4秒,那么在主循环中,您需要确保上一个作业在生成新作业之前完成。

但是,time.sleep()本身可以漂移,因为不保证线程实际被挂起多长时间。 正确这样做的方法是弄清楚工作花了多长时间并在剩余的时间间隔内休眠。我认为这就是UI和游戏渲染引擎的工作原理,它们必须在固定时间每秒显示固定数量的帧,并且每帧渲染可能需要不同的时间才能完成。