Search code examples
pythonreal-timeembedded-linuxgevent

Can we use gevent.sleep() for precise timings?


Can we use gevent.sleep() anywhere in our application or gevent.monkey.patch_time() on any third party libraries without an issue, especially precise timings takes place?

For example, some libraries use time.sleep() function in order to measure a couple of microseconds that is used to control an embedded (dot matrix LCD and such) device. Can we safely monkey patch such libraries without a problem?


Solution

  • No. gevent.sleep() is not suitable for precise timings.

    Here is the test code:

    import gevent
    import time
    
    
    for i in range(10):
            test_duration = 0.1 ** i
            start_time = time.time()
            gevent.sleep(test_duration)
            end_time = time.time()
    
            gevent_duration = end_time - start_time
    
            err = (gevent_duration - test_duration) / test_duration
            print("test_duration: %.10f secs, err: %%%.10f" % (test_duration, err))
    

    Here is the result:

    ceremcem@cca-erik:gevent-timing-test$ python test.py 
    test_duration: 1.0000000000 secs, err: %0.0009050369
    test_duration: 0.1000000000 secs, err: %0.0037088394
    test_duration: 0.0100000000 secs, err: %0.0192871094
    test_duration: 0.0010000000 secs, err: %0.1119842529
    test_duration: 0.0001000000 secs, err: %9.9791755676
    test_duration: 0.0000100000 secs, err: %108.9109649658
    test_duration: 0.0000010000 secs, err: %1095.0102081299
    test_duration: 0.0000001000 secs, err: %10878.0397644043
    test_duration: 0.0000000100 secs, err: %108407.9279174804
    test_duration: 0.0000000010 secs, err: %1087902.9764404292
    ceremcem@cca-erik:gevent-timing-test$ python test.py 
    test_duration: 1.0000000000 secs, err: %0.0009670258
    test_duration: 0.1000000000 secs, err: %0.0031008720
    test_duration: 0.0100000000 secs, err: %0.0271072388
    test_duration: 0.0010000000 secs, err: %0.1529922485
    test_duration: 0.0001000000 secs, err: %10.1293792725
    test_duration: 0.0000100000 secs, err: %117.3032989502
    test_duration: 0.0000010000 secs, err: %1191.0928955078
    test_duration: 0.0000001000 secs, err: %11898.4712829590
    test_duration: 0.0000000100 secs, err: %119089.0802612304
    test_duration: 0.0000000010 secs, err: %1188992.4539794917
    

    As you can see, errors are also unpredictable.

    That's why gevent.monkey.patch_all() should be used carefully in such situations.