如何使用python以特定频率触发事件

2024-03-29 11:39:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我想以特定频率触发事件,例如44100hz。
我希望下面的代码每秒执行“print”44100次,但事实并非如此

import time

frequency = 44100
desired_interval = 1 / frequency

events = 0

time_now = time.time()
time_end = time_now +1

while time_now < time_end:

    events += 1
    print(events)

    # some time has passed, sleep for desired interval less passed time
    if( desired_interval > ( time.time() - time_now ) ):
        time.sleep( desired_interval - ( time.time() - time_now ) )

    time_now = time.time()    

Tags: 代码importtime事件sleepeventsnow事实
2条回答

这更接近,即使“打印”事件很可能(非常肯定)不是以固定频率触发的

import time

frequency = 44100
desired_interval = 1 / frequency

events = 0

time_now = time.time()
time_start = time_now
time_end = time_now +1

while time_now < time_end:

    events += 1
    print(events)

    if( desired_interval * events > ( time.time() - time_start ) ):
        # abs mitigate the fact that sometime the result is negative.
        time.sleep( abs( desired_interval * events - ( time.time() - time_start ) ) )


    time_now = time.time()

要了解为什么事情花费的时间比您想象的要长,我们必须使用探查器

将代码保存为timer.py后,我运行了以下命令:

python3 -m cProfile -s tottime timer.py

结果是:

37621
37622
37623
37624
37625
37626
         188134 function calls in 1.000 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    37626    0.840    0.000    0.840    0.000 {built-in method time.sleep}
    37626    0.104    0.000    0.104    0.000 {built-in method builtins.print}
        1    0.045    0.045    1.000    1.000 timer.py:1(<module>)
   112879    0.012    0.000    0.012    0.000 {built-in method time.time}
        1    0.000    0.000    1.000    1.000 {built-in method builtins.exec}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

所以,在我的机器上,它每秒运行37626次。 大部分时间都花在运行time.sleep()

问题是,在计算延迟时,您没有考虑python代码运行所需的时间。 它也没有考虑到Python是在运行其他程序的操作系统之上运行的

让我们将程序简化为:

import time

frequency = 44100
desired_interval = 1 / frequency * 0.72
events = 0
time_now = time.time()
time_end = time_now + 1
while time_now < time_end:
    events += 1
    print(events)
    time.sleep(desired_interval)
    time_now = time.time()

在我的系统上,这大约每秒打印44100次。如你所见,我不得不将睡眠时间减少约30%,以将开销考虑在内。这只是一个玩具程序

查看所需的频率,您似乎希望实时执行CD质量的音频处理。 老实说,Python可能不是这方面的正确选择

你应该做的是把你想做的实际工作包装在一个函数中,然后在这个函数上运行分析器。分析的结果将告诉您是否可以在所需的时间内完成所需的工作

如果你不能,有一些加速的选择

  • 使用numpy
  • 使用cython
  • 使用pypy

相关问题 更多 >