Sleep for exact time in python

前端 未结 7 1463
迷失自我
迷失自我 2020-12-11 17:17

I need to wait for about 25ms in one of my functions. Sometimes this function is called when the processor is occupied with other things and other times it has the processor

相关标签:
7条回答
  • 2020-12-11 17:34

    Another solution for accurate timings and delay is to use the perf_counter() function from module time. Especially useful in windows as time.sleep is not accurate in milliseconds. See below example where function accurate_delay creates a delay in millisecond.

    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))
    
    0 讨论(0)
  • 2020-12-11 17:40

    Because you're working with a preemptive operating system, there's no way you can guarantee that your process will be able to have control of the CPU in 25ms.

    If you'd still like to try, it would be better to have a busy loop that polls until 25ms has passed. Something like this might work:

    import time
    target_time = time.clock() + 0.025
    while time.clock() < target_time:
        pass
    
    0 讨论(0)
  • 2020-12-11 17:44

    What you intend to do is a real time application. Python (and probably the OS you are using) is not intended to program this kind of applications, where time restriction is so strict.

    In order for you to achieve what you are looking for you need a RTOS (Real Time Operating System) and develop your application using a suitable programming language (usually C) following RT best practises.

    0 讨论(0)
  • 2020-12-11 17:50

    0.25 seconds are 250 ms, not 25. Apart from this, there is no way to wait for exactly 25 ms on common operating systems – you would need some real-time operating system.

    0 讨论(0)
  • 2020-12-11 17:50

    Edit: in Windows 10 this nonsense seems unnecessary. Try it like so:

    >>> from time import sleep
    >>> import timeit
    >>> '%.2f%% overhead' % (timeit.timeit('sleep(0.025)', number=100, globals=globals()) / 0.025 - 100)
    '0.29% overhead'
    

    .29%, or thereabout, is fairly low overhead, and usually more than accurate enough.

    Previous Windows versions will by default have a sleep resolution of 55 msecs, which means your sleep call will take somewhere between 25 and 55 msecs. To get the sleep resolution down to 1 millisecond you need to set the resolution used by Windows by calling timeBeginPeriod:

    import ctypes
    winmm = ctypes.WinDLL('winmm')
    winmm.timeBeginPeriod(1)
    
    0 讨论(0)
  • 2020-12-11 17:51

    What system are you on? If you're on Windows you may want to do something like this for exact timing:

    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)
    

    This code will pretty much guarentee your process will sleep .25 seconds. Watch out though- you may want to lower the priority to 2 or 3 unless it's absolutely critical that this sleeps for .25 seconds. Certainly don't change the priority too high for a user-end product.

    0 讨论(0)
提交回复
热议问题