Python中timer.sleep精度不足:寻求高精度定时器解决方案
time.sleep() in Python Great question—when you're working on a project that demands rock-solid timer precision, time.sleep() is basically a non-starter. As you noticed, OS scheduling overhead means it can introduce extra delays, and those errors add up over time. Let's break down some better solutions:
1. Busy Waiting with time.perf_counter()
If you need microsecond-level precision for short sleep intervals, a busy wait loop using time.perf_counter() (Python's highest-resolution timer) is your best bet. It works by constantly checking if the desired time has passed, so it minimizes scheduling delays.
import time def precise_short_sleep(seconds): start_time = time.perf_counter() while time.perf_counter() - start_time < seconds: # Do nothing—just wait pass
Note: This will hog a CPU core while waiting, so it's only ideal for very short sleep periods (like < 100ms). For longer waits, you'll want a lower-CPU alternative.
2. Hybrid Sleep with select (Unix/Linux) or Win32 Events (Windows)
For longer intervals where you don't want to waste CPU, combine a low-overhead sleep call with periodic checks using time.perf_counter() to correct for scheduling delays.
Unix/Linux Solution
Use select.select()—its timeout parameter has much better precision than time.sleep() on Unix systems:
import time import select def precise_sleep(seconds): end_time = time.perf_counter() + seconds remaining = seconds while remaining > 0: # Wait with select, then recalculate remaining time select.select([], [], [], remaining) remaining = end_time - time.perf_counter()
Windows Solution
On Windows, use the Win32 API's event waiting functions (requires the pywin32 package):
import time import win32event import win32api def precise_sleep(seconds): end_time = time.perf_counter() + seconds remaining = seconds while remaining > 0: # Convert remaining time to milliseconds for the API call win32event.WaitForSingleObject(win32event.CreateEvent(None, False, False), int(remaining * 1000)) remaining = end_time - time.perf_counter()
This approach keeps CPU usage low while adjusting for any scheduling delays that happen during the wait.
3. Adjust Process Priority
OS scheduling is often the biggest culprit for delayed wake-ups. Boosting your process's priority can make the OS more likely to schedule it immediately when the sleep interval ends.
Unix/Linux
Use os.nice() (requires root privileges for higher priorities):
import os # Lower the "nice" value (higher priority; range is -20 to 19) os.nice(-10)
Windows
Use pywin32 to set the process priority class:
import win32process import win32api process_handle = win32api.GetCurrentProcess() # Set to HIGH_PRIORITY_CLASS (or REALTIME_PRIORITY_CLASS for extreme cases) win32process.SetPriorityClass(process_handle, win32process.HIGH_PRIORITY_CLASS)
Warning: Don't overdo this—setting a process to real-time priority can starve other system processes. Use high priority only when absolutely necessary.
4. Third-Party Libraries (Optional)
If you want a pre-built solution, libraries like precision-timer wrap these low-level techniques into an easy-to-use API:
pip install precision-timer
from precision_timer import PrecisionTimer timer = PrecisionTimer() timer.sleep(0.001) # Sleep for 1ms with high precision
内容的提问来源于stack exchange,提问作者Darren Christopher

