python周期性执行函数

       脚本中自定义了多个非阻塞型函数,这些函数有的需要每1秒执行一次,有的需要每2秒,或自定义的周期来执行。具体函数的调用周期标明在其函数名上,如函数名“job_4_cycle_seconds_1”的含义是job_4以每1秒钟一次的周期调用。

       以下为实现该场景的脚本框架:

import threading
import types
import re
import time
from functools import reduce
import math
from collections import defaultdict
from threading import Event
import signal


run_event = Event()


def on_kill(signum, frame):
    run_event.set()
    print("finish")


def lcm(a, b):
    return abs(a*b) // math.gcd(a, b)


def lcm_multiple(numbers):
    return reduce(lcm, numbers)


def job_1_cycle_seconds_1():
    print(f"job 1")


def job_4_cycle_seconds_1():
    print(f"job 4")


def job_2_cycle_seconds_2():
    print(f"job 2")


def job_5_cycle_seconds_2():
    print(f"job 5")


def job_3_cycle_seconds_5():
    print(f"job 3")


def job_6_cycle_seconds_7():
    print(f"job 6")


def xx_1():
    print(f"nothing")


def xx_2():
    print(f"nothing")
    

def main_loop(cycle_jobs_dict: dict):
    clock = 1
    time_step_seconds = 1
    cycle_max_seconds = lcm_multiple(list(cycle_jobs_dict.keys()))
    print("start")
    while not run_event.is_set():
        for cycle, jobs in cycle_jobs_dict.items():
            if clock % cycle == 0:
                for job in jobs:
                    job()
        clock = (clock + 1) % cycle_max_seconds
        time.sleep(time_step_seconds)


if __name__ == "__main__":
    signal.signal(signal.SIGINT, on_kill)
    signal.signal(signal.SIGTERM, on_kill)
    cycle_jobs = defaultdict(list)
    current_module = globals()
    functions = {name: obj for name, obj in current_module.items()
                 if isinstance(obj, types.FunctionType)}
    cycle_seconds_pattern = r'cycle_seconds_(\d+)'
    for function_name, function_obj in functions.items():
        cycle_time = re.findall(cycle_seconds_pattern, function_name)
        if cycle_time:
            cycle_time = int(cycle_time[0])
            cycle_jobs[cycle_time].append(function_obj)
    main_loop(cycle_jobs)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值