周期性功能执行,时间间隔< 100 ms

Periodic function execution with time interval < 100 ms

提问人:Wör Du Schnaffzig 提问时间:10/19/2020 最后编辑:Wör Du Schnaffzig 更新时间:10/19/2020 访问量:503

问:

我的目标是在周期性的时间间隔内执行一个函数,但周期很长。 下面链接的代码似乎很有前途:
https://medium.com/greedygame-engineering/an-elegant-way-to-run-periodic-tasks-in-python-61b7c477b679。 经过一些小的修改,我最终得到了这个:

import threading
import time
from datetime import timedelta
from unittest.mock import Mock

WAIT_TIME_SECONDS = 0.1

class PeriodicTask(threading.Thread):
    """ Class for executing a periodic task specifying a time interval between invokations """
    def __init__(self, interval: timedelta, execute: Callable[..., None], *args, **kwargs):
        super().__init__()
        assert isinstance(interval, timedelta), "Must specifiy datetime time interval, here"
        assert not execute is None, "Must specify function which should be invoked regularly, here"

        self.daemon = False
        self.stopped = threading.Event()
        self.interval = interval
        self.execute = execute
        self.args = args
        self.kwargs = kwargs

    def stop(self):
        """ Stop periodic task """
        self.stopped.set()
        self.join()

    def run(self):
        """ Run task based on the specified interval """
        while not self.stopped.wait(self.interval.total_seconds()):
            self.execute(*self.args, **self.kwargs)

if __name__ == "__main__":
    foo = Mock()
    job = PeriodicTask(interval=timedelta(seconds=WAIT_TIME_SECONDS), execute=foo)
    job.start()

    time.sleep(1)
    job.stop()

似乎我可以执行大约 100 毫秒的定期任务(Intel Core i7-3770K CPU,3.5 GHz,16 GB RAM),然后任务相互阻碍。有没有办法优化这个代码片段,这样我就可以定期执行任务,时间至少达到 10 毫秒?

python-3.x 多线程 定期任务

评论

0赞 Abhinav Mathur 10/19/2020
你尝试过并行化吗?
0赞 Wör Du Schnaffzig 10/19/2020
我想在每次经过给定的时间间隔时执行指定的函数。我不想并行执行它。回调函数具有“观察者”的角色,最终观察某种状态。但这只是最小的例子。我不应该称它为“foo”。我的错。我确实应该称它为:“观察者”
0赞 Wör Du Schnaffzig 10/19/2020
将以下行添加到代码中:并减少 until the 将不再更改其值。print (f"Called function {foo.call_count} times.")WAIT_TIME_SECONDScall_count
0赞 ChatterOne 10/19/2020
@pqans 每个操作系统在实时性方面都有其局限性。再加上你期望做的事情的开销,你很快就会得到一些限制。随着您的代码的减少,直到大约 100 毫秒才会给出线性结果,但即使值为 ,它仍然会发生变化,即使它不会只是更低(例如,我得到大约 25.000)。对我来说,它在 1/10.000.000 秒停止变化,但它“仅”显示 100.000 次运行(而不是一千万次)。在某些时候,你编写的任何代码都会使情况变得更糟。WAIT_TIME_SECONDS0.00001900000.0000001
0赞 Wör Du Schnaffzig 10/19/2020
似乎唯一的方法是使用time.perf_counter回退到老式民意调查。另一方面,我不想perf_counters分散在我的代码中。

答: 暂无答案