我试图做一个非常简单的节拍器,它以30 bpm的速度工作:
While True:
winsound.Beep(1000, 200)
time.sleep(2 - 0.2)
然后,我同时打开手机上的节拍器应用程序和计算机中的蜂鸣声,随着时间的流逝,它变得越来越不精确。 还有另一种方法可以执行“ time.sleep()”吗?甚至是“ time.sleep()”的内gui吗?
答案 0 :(得分:3)
在多任务操作系统上很难做到这一点:要给系统精确的sleep
延迟并不容易。有关详情,请参见How accurate is python's time.sleep()?。
但是,通过测量时间跨度并调整睡眠延迟,我们可以相当接近。 Python 3.3+提供了time.perf_counter
,尽管确切的精度取决于您的操作系统和硬件,但是它可以很好地测量时间间隔。
这是一个简单的演示,仅显示每个刻度的请求延迟和测量延迟之间的差异。初始输出有些草率,但很快就稳定下来,使滴答声落在请求间隔的10微秒内。但是,播放声音比打印到终端需要更多的系统资源,这可能会影响该技术的精度。为了获得最佳结果,请最小化计算机上的任务负载,尤其是在单核计算机上。
我将延迟设置为0.2秒= 300 bpm。较慢的节拍速率可能会导致 精度降低,因为在每个睡眠周期中,CPU都有更多时间执行其他任务,这可能会导致睡眠时间比请求的时间长一点。
from time import sleep, perf_counter
delay = d = 0.2
print(60 / delay, 'bpm')
prev = perf_counter()
for i in range(20):
sleep(d)
t = perf_counter()
delta = t - prev - delay
print('{:+.9f}'.format(delta))
d -= delta
prev = t
典型输出
300.0 bpm
+0.000262488
+0.000151862
-0.000019085
-0.000011358
+0.000023078
-0.000015817
-0.000004357
+0.000009283
-0.000012252
+0.000020515
-0.000009061
+0.000003249
-0.000011482
+0.000029230
+0.000001554
-0.000023614
-0.000003286
+0.000000127
-0.000003732
+0.000016311
这些结果来自运行Linux的旧单核32位2GHz计算机YMMV。