関数の 1 つで約 25ms 待つ必要があります。この関数は、プロセッサが他のことで占有されているときに呼び出されることもあれば、プロセッサをすべて独り占めしているときに呼び出されることもあります。
試してみましtime.sleep(.25)
たが、実際には25ミリ秒になることもあれば、もっと時間がかかることもあります。プロセッサの可用性に関係なく、正確な時間スリープする方法はありますか?
プリエンプティブなオペレーティング システムを使用しているため、プロセスが 25 ミリ秒で CPU を制御できることを保証する方法はありません。
それでも試してみたい場合は、25ms が経過するまでポーリングするビジー ループを用意することをお勧めします。このようなものがうまくいくかもしれません:
import time
target_time = time.clock() + 0.025
while time.clock() < target_time:
pass
0.25 秒は 25 ミリ秒ではなく 250 ミリ秒です。これとは別に、一般的なオペレーティング システムで正確に25 ミリ秒待機する方法はありません。リアルタイム オペレーティング システムが必要になります。
どのシステムを使用していますか? Windows を使用している場合は、正確なタイミングを得るために次のようなことを行うことができます。
import ctypes
kernel32 = ctypes.windll.kernel32
# This sets the priority of the process to realtime--the same priority as the mouse pointer.
kernel32.SetThreadPriority(kernel32.GetCurrentThread(), 31)
# This creates a timer. This only needs to be done once.
timer = kernel32.CreateWaitableTimerA(ctypes.c_void_p(), True, ctypes.c_void_p())
# The kernel measures in 100 nanosecond intervals, so we must multiply .25 by 10000
delay = ctypes.c_longlong(.25 * 10000)
kernel32.SetWaitableTimer(timer, ctypes.byref(delay), 0, ctypes.c_void_p(), ctypes.c_void_p(), False)
kernel32.WaitForSingleObject(timer, 0xffffffff)
このコードは、プロセスが 0.25 秒スリープすることをほぼ保証します。ただし、注意してください。これが 0.25 秒間スリープすることが絶対に重要でない限り、優先度を 2 または 3 に下げることをお勧めします。確かに、ユーザーエンド製品の優先度を高くしすぎないようにしてください。
正確なタイミングと遅延の別の解決策は、モジュール時間から perf_counter() 関数を使用することです。time.sleep はミリ秒単位で正確ではないため、Windows で特に役立ちます。関数 accuracy_delay がミリ秒単位で遅延を作成する以下の例を参照してください。
import time
def accurate_delay(delay):
''' Function to provide accurate time delay in millisecond
'''
_ = time.perf_counter() + delay/1000
while time.perf_counter() < _:
pass
delay = 10
t_start = time.perf_counter()
print('Wait for {:.0f} ms. Start: {:.5f}'.format(delay, t_start))
accurate_delay(delay)
t_end = time.perf_counter()
print('End time: {:.5f}. Delay is {:.5f} ms'.
format(t_end, 1000*(t_end - t_start)))
sum = 0
ntests = 1000
for _ in range(ntests):
t_start = time.perf_counter()
accurate_delay(delay)
t_end = time.perf_counter()
print('Test completed: {:.2f}%'.format(_/ntests * 100), end='\r', flush=True)
sum = sum + 1000*(t_end - t_start) - delay
print('Average difference in time delay is {:.5f} ms.'.format(sum/ntests))
あなたがしようとしていることは、リアルタイムアプリケーションです。Python (およびおそらく使用している OS) は、時間制限が非常に厳しいこの種のアプリケーションをプログラミングすることを意図していません。
探しているものを実現するには、RTOS (リアルタイム オペレーティング システム) が必要であり、RT のベスト プラクティスに従って、適切なプログラミング言語 (通常は C) を使用してアプリケーションを開発します。
sleep メソッドのドキュメントから:
指定された秒数だけ実行を中断します。引数は、より正確なスリープ時間を示す浮動小数点数である場合があります。実際の一時停止時間は、要求された時間よりも短い場合があります。これは、キャッチされたシグナルは、そのシグナルのキャッチ ルーチンの実行後に sleep() を終了するためです。また、システム内の他のアクティビティのスケジューリングが原因で、一時停止時間が要求された時間よりも任意の量だけ長くなる場合があります。
実際には、基盤となる OS に依存します。