天天看點

python簡單的time ticker

在某些時候,我們需要精确的啟動一個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