python 定时启动函数

python 定时启动函数

# -*- coding:utf-8 -*-
import time
from datetime import datetime
import ctypes as ct
from ctypes.wintypes import UINT, DWORD
from typing import Callable, Optional

class mmPeriodicTimer:
    """Periodic timer based upon the Windows Multimedia library
    This produces a timed callback with high precision ( ~ < 1ms difference)
    executed outside of a threaded structure (based on Windows runtime ).
    The advantage of this is that the Python GIL limitation is avoided,
    and an aligned "lag" time between all Python processes is not generated;

    The disadvantage is that since this is thread independent, the callback
    procedure must complete its tasks before the next callback is executed
    otherwise collisions may occur

    This is based on the example:
    https://stackoverflow.com/questions/10717589/how-to-implement-high-speed-consistent-sampling
    """

    timeproc = ct.WINFUNCTYPE(None, ct.c_uint, ct.c_uint, DWORD, DWORD, DWORD)
    timeSetEvent = ct.windll.winmm.timeSetEvent
    timeKillEvent = ct.windll.winmm.timeKillEvent

    def Tick(self):
        self.i_reps += 1
        self.tickFunc()

        if not self.periodic:
            self.stop()

        if self.n_reps is not None and self.i_reps >= self.n_reps:
            self.stop()

    def CallBack(self, uID, uMsg, dwUser, dw1, dw2):
        if self.running:
            self.Tick()

    def __init__(
        self,
        interval: int,
        tickfunc: Callable,
        resolution: Optional[int] = 0,
        stopFunc: Optional[Callable] = None,
        periodic: Optional[bool] = True,
        n_reps: Optional[int] = None,
    ):
        self.interval = UINT(int(interval * 1000))
        self.resolution = UINT(int(resolution * 1000))
        self.tickFunc = tickfunc
        self.stopFunc = stopFunc
        self.periodic = periodic
        self.n_reps = n_reps
        if not self.periodic and self.n_reps is not None:
            raise ValueError("n_reps must be None if periodic is False")

        self.i_reps = 0
        self.id = None
        self.running = False
        self.calbckfn = self.timeproc(self.CallBack)

    def start(self, instant: bool = False):
        if not self.running:
            self.running = True
            if instant:
                self.Tick()

            self.id = self.timeSetEvent(
                self.interval,
                self.resolution,
                self.calbckfn,
                ct.c_ulong(0),
                ct.c_uint(self.periodic),
            )

    def stop(self):
        if self.running:
            self.timeKillEvent(self.id)
            self.running = False

            if self.stopFunc:
                self.stopFunc()


def my_func():
    print("current time=", datetime.now())


# interval 每个任务间隔时间
# tickfunc 启动函数
# periodic 默认True 一直调用函数,直到时间截至; False 只调用一次
# n_reps 调用函数次数, 当被使用时,periodic必须为True
t = mmPeriodicTimer(interval=1, tickfunc=my_func, periodic=False)
t.start()
time.sleep(5)
t.stop()

参考文档: How to implement high speed, consistent sampling?

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值