在某些时候,我们需要精确的启动一个func,如果用time.sleep简单的轮询,会因为执行的任务阻塞,或者其他原因导致无法精确的定时执行。
例如在采集某些数据的时候,需要精确的每60秒采集一次,如果直接简单的轮询:{1:计时1,2:采集,3:计时2,4:sleep(60-计时2-计时1)},正常的时候看起来没什么问题。
但是如果在第二步“采集”的时候阻塞超过60秒,那就会导致后续的采集延迟了。
因此需要一个新的定时器,精确的定时触发操作,不管每一步操作有没有完成,到下一个时刻都要开始触发新的操作。
如下代码,每隔4s触发
do_job
这个函数,在这个函数中,如果触发次数是3的倍数,则sleep 5,其他则sleep 2。
import threading
import time
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s"
)
def do_job(count):
logging.info("[%s] start job" % count)
if count % 3 == 0:
time.sleep(5)
else:
time.sleep(2)
logging.info("[%s] end job" % count)
def thread_time_running(max_runs=10):
alive_timers = []
for i in range(0, max_runs):
t = threading.Timer(4, do_job, [i,])
logging.info("starting thread %d" % i)
t.start()
logging.info("warning thread %d" % i)
t.join(timeout=4)
if t.is_alive():
alive_timers.append(t)
for i, t in enumerate(alive_timers):
if t.is_alive():
t.join()
thread_time_running()
执行之后如下:
2021-03-17 20:49:50,736 - INFO - starting thread 0
2021-03-17 20:49:50,736 - INFO - warning thread 0
2021-03-17 20:49:54,742 - INFO - [0] start job
2021-03-17 20:49:54,742 - INFO - starting thread 1
2021-03-17 20:49:54,742 - INFO - warning thread 1
2021-03-17 20:49:58,748 - INFO - [1] start job
2021-03-17 20:49:58,748 - INFO - starting thread 2
2021-03-17 20:49:58,749 - INFO - warning thread 2
2021-03-17 20:49:59,746 - INFO - [0] end job
2021-03-17 20:50:00,753 - INFO - [1] end job
2021-03-17 20:50:02,754 - INFO - starting thread 3
2021-03-17 20:50:02,754 - INFO - [2] start job
2021-03-17 20:50:02,755 - INFO - warning thread 3
2021-03-17 20:50:04,755 - INFO - [2] end job
2021-03-17 20:50:06,759 - INFO - [3] start job
2021-03-17 20:50:06,759 - INFO - starting thread 4
2021-03-17 20:50:06,760 - INFO - warning thread 4
2021-03-17 20:50:10,765 - INFO - [4] start job
2021-03-17 20:50:10,765 - INFO - starting thread 5
2021-03-17 20:50:10,766 - INFO - warning thread 5
2021-03-17 20:50:11,761 - INFO - [3] end job
2021-03-17 20:50:12,770 - INFO - [4] end job
2021-03-17 20:50:14,771 - INFO - [5] start job
2021-03-17 20:50:14,771 - INFO - starting thread 6
2021-03-17 20:50:14,772 - INFO - warning thread 6
2021-03-17 20:50:16,775 - INFO - [5] end job
2021-03-17 20:50:18,774 - INFO - [6] start job
2021-03-17 20:50:18,774 - INFO - starting thread 7
2021-03-17 20:50:18,774 - INFO - warning thread 7
2021-03-17 20:50:22,777 - INFO - starting thread 8
2021-03-17 20:50:22,777 - INFO - [7] start job
2021-03-17 20:50:22,778 - INFO - warning thread 8
2021-03-17 20:50:23,776 - INFO - [6] end job
2021-03-17 20:50:24,783 - INFO - [7] end job
2021-03-17 20:50:26,783 - INFO - starting thread 9
2021-03-17 20:50:26,783 - INFO - [8] start job
2021-03-17 20:50:26,784 - INFO - warning thread 9
2021-03-17 20:50:28,786 - INFO - [8] end job
2021-03-17 20:50:30,787 - INFO - [9] start job
2021-03-17 20:50:35,790 - INFO - [9] end job