usleep in Python

后端 未结 8 989
执笔经年
执笔经年 2020-12-09 02:58

I was searching for a usleep() function in Python 2.7.

Does anybody know if it does exist, maybe with another function name?

8条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-09 03:00

    An alternate sleep function for python.

    Note: Should not be used for multiple threads due to GIL lock, but for multiple subprocesses its fine. Same with time.sleep()

    I'm wrapping a C function to Python. I'm using nanosleep() of C library, which halts that thread running for that much amount of time. It is not a busy-wait type of delay which uses much CPU to evaluate some math. The codes are as follows. Put all in a folder, say CWrapper.

    C_functions.h

    #include 
    int c_sleep_msec(long milliseconds);
    int c_sleep_nsec(long nanoseconds);
    

    C_functions.c

    #include "C_functions.h"
    int c_sleep_msec(long milliseconds) {
        struct timespec req;
        //struct timespec rem;
        if(milliseconds > 999) {
          req.tv_sec = (int)(milliseconds / 1000);  /* Must be Non-Negative */
          req.tv_nsec = (milliseconds - ((long)req.tv_sec * 1000)) * 1000000; /* Must be in range of 0 to 999999999 */
        }
        else {
          req.tv_sec = 0;                         /* Must be Non-Negative */
          req.tv_nsec = milliseconds * 1000000;    /* Must be in range of 0 to 999999999 */
        }
        //rem = NULL;
        return nanosleep(&req , NULL);
    }
    //------------------------------------------------------
    int c_sleep_nsec(long nanoseconds) {
        struct timespec req;
        //struct timespec rem;
        if (nanoseconds > 999999999) {
          req.tv_sec = (int)(nanoseconds / 1000000000);
          req.tv_nsec = (nanoseconds - ((long)req.tv_sec * 1000000000));
        }
        else {
          req.tv_sec = 0;
          req.tv_nsec = nanoseconds;
        }
        //rem = NULL;
        return nanosleep(&req , NULL);
    }
    

    You can also create a function for micro seconds using the same nanosleep()

    CWrapper.pyx

    cdef extern from "C_functions.h":
        int c_sleep_msec(long milliseconds)
        int c_sleep_nsec(long nanoseconds)
    
    def sleep_msec(milliseconds):
        return c_sleep_msec(milliseconds)
    
    def sleep_nsec(nanoseconds):
        return c_sleep_nsec(nanoseconds)
    

    setup.py

    from distutils.core import setup
    from distutils.extension import Extension
    from Pyrex.Distutils import build_ext
    
    setup(
      name = "CWrapper",
      ext_modules=[ Extension("CWrapper", ["CWrapper.pyx", "C_functions.c"]) ],
      cmdclass = {'build_ext': build_ext}
    )
    

    Install python-pyrex. Then run in linux terminal

    python setup.py build_ext -i
    

    It will create CWrapper.c, build, and CWrapper.so files. Use CWrapper.so where ever you want, and just import in python.

    Note: Compile separately for Raspberry Pi.

    Now, test the function

    Test_sleep.py

    import serial
    from multiprocessing import Process
    import time
    import CWrapper
    
    
    class TestSleep:
        def __init__(self):
            self.delay_sec = 0.00000100
            self.delay_msec = 30
            self.delay_nsec = 1000 #200000000
            self.start_time = time.time()
    
            self.process_1 = Process(name="process_1", target=self.process_1_task, args=("process_1",))
            self.process_1.daemon = True
            self.process_1.start()
    
            self.process_2 = Process(name="process_2", target=self.process_1_task, args=("process_2",))
            self.process_2.daemon = True
            self.process_2.start()
    
            self.process_3 = Process(name="process_3", target=self.process_1_task, args=("process_3",))
            self.process_3.daemon = True
            self.process_3.start()
    
        def process_1_task(self, process_name):
            start = self.start_time
            delay_msec = self.delay_msec
            delay_sec = self.delay_sec
            delay_nsec = self.delay_nsec
    
            t1 = start
            for i in range(1, 81):
                status = CWrapper.sleep_msec(delay_msec)
                # status = CWrapper.sleep_nsec(delay_nsec)
                #status = time.sleep(delay_sec)
                t2 = time.time()
                elapsed_time = t2 - t1
                t1 = t2
                print process_name, i, "status:", status, "Elapsed-time:", elapsed_time
    
    
    if __name__ == '__main__':
        test = TestSleep()
        # for i in range(1,10000):
        #     print "main thread", i
            # time.sleep(0.1)
        while True:    # Since daemon=True, main thread should check join() or stay in loop
            pass
    

    Vary the parameters delay_sec for time.sleep(), delay_msec for CWrapper.sleep_msec(), delay_nsec for CWrapper.sleep_nsec(). Uncomment the function which you want to test in thread_1_task().

提交回复
热议问题