问题
Following on from this post, I've identified a non-functional implementation of Python's time.sleep() function under Windows 7 (Enterprise, 64-bit and Python 3.4.4).
Here's the reference .py script:
import threading, time
def Return():
return
def Setup():
for _ in range(10):
time_before = time.time()
Return()
wait_delay = -time.time()
delays = []
InputFrequency = 60
while (time.time() - time_before) < (1 / InputFrequency):
time.sleep(0)
wait_delay += time.time()
delays.append(wait_delay)
print("Output frequency: " + str([1/t for t in delays][0]) + " Hz")
threading.Thread(target=Setup).start()
As per this example, this script should produce output frequencies of roughly 60Hz. However, when run on my Windows 7 Enterprise machine, these are the outputs frequencies I receive for a given input frequency:
Input: 10Hz - Output: 9.15Hz
Input: 20Hz - Output: 16.03Hz
Input: 30Hz - Output 21.37Hz
Input Range: 40Hz - 64Hz - Output: 32.05Hz
Input Range: 65Hz - 10kHz+ - Output: 64.10Hz
What is going on here? Why are varying input frequencies (above 40Hz) producing the same output frequency? Why is the output frequency upper limit 64.10Hz, even when the input frequency is over 10,000Hz? I don't believe it's a time.sleep() resolution issue at ~60Hz. The same input frequency values supplied to the ideone.com script produce the expected output frequencies, so it must be related to my computer.
回答1:
Python makes very few guarantees about how these calls will behave, especially cross-platform. There are two things that can potentially go wrong here - time.time()
's resolution is worse than the resolution you're trying to achieve or sleep
's resolution is.
Sleep should be roughly at least 1 to 2 ms accurate on recent platforms as reported here:
How accurate is python's time.sleep()?
This leaves time.time()
. The documentation for this particular call warns the accuracy may be poor:
Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.
Fortunately, a higher resolution clock API is provided in time.perf_counter()
which attempts to access the highest resolution clock available on platform. From the documentation:
Return the value (in fractional seconds) of a performance counter, i.e. a clock with the highest available resolution to measure a short duration. It does include time elapsed during sleep and is system-wide. The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid.
In the case of Windows, this seems to be better than 60Hz which corrects your problem.
来源:https://stackoverflow.com/questions/43772960/inaccurate-time-sleep-with-python-3-x-and-windows-7