44

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

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

codeforester
  • 39,467
  • 16
  • 112
  • 140
Federico Zancan
  • 4,846
  • 4
  • 44
  • 60
  • It seems no to be clearly stated in answers: `time.sleep` function is able to consume a float number, for example a fraction of second. Thus, `time.sleep(0.1)` sleeps for 100ms. – Robson May 18 '21 at 09:06

9 Answers9

56

Since usleep generally means you want to delay execution for x microseconds, you must divide the seconds value by 1000000.

import time
time.sleep(seconds/1000000.0)

time.sleep() takes seconds as a parameter.

http://docs.python.org/library/time.html#time.sleep

Mike Lewis
  • 63,433
  • 20
  • 141
  • 111
  • 21
    Careful, read up on the [accuracy of sleep()](http://stackoverflow.com/questions/1133857/how-accurate-is-pythons-time-sleep) – x29a Jul 18 '15 at 12:27
  • You must divide the *microseconds* value, not the *seconds* value – altermetax Aug 03 '23 at 00:41
28
import time
usleep = lambda x: time.sleep(x/1000000.0)

usleep(100) #sleep during 100μs
okm
  • 23,575
  • 5
  • 83
  • 90
Fábio Diniz
  • 10,077
  • 3
  • 38
  • 45
11

Three lines to call the "original" usleep:

import ctypes

libc = ctypes.CDLL('libc.so.6')
libc.usleep(300000)

tested on centos & alpine both python 3.8.1

mertyildiran
  • 6,477
  • 5
  • 32
  • 55
8

Be very very careful with time.sleep. I got burned by python3 using time.sleep because it is non-monotonic. If the wall clock changes backwards, the time.sleep call won't finish until the wall clock catches up with where it would have been if the sleep had gone forward as planned. I have not yet found a monotonic blocked sleep for python.

Instead, I recommend Event.wait, like this:

def call_repeatedly(interval, func, *args, **kwargs):
    stopped = Event()
    def loop():
        while not stopped.wait(interval):  # the first call is in `interval` secs
            try:
                func(*args)
            except Exception as e:
                logger.error(e);
                if kwargs.get('exception'):
                    kwargs.get('exception')(e) # SEND exception to the specified function if there is one.
                else:
                    raise Exception(e)
    Thread(target=loop).start()
    return stopped.set

http://pastebin.com/0rZdY8gB

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
SynaTree
  • 361
  • 3
  • 4
  • 7
    I believe `time.sleep` should now be monotonic in Python 3; at least, the [source code](https://github.com/python/cpython/blob/v3.6.3/Modules/timemodule.c#L1430) says `_PyTime_GetMonotonicClock()` to get the current time. I can't say for sure what the past behavior was like. – user2357112 Oct 26 '17 at 00:16
  • I don't see any python doc. reference that says _time.sleep_ is monotonic. The time module in Python3 has the function `monotonic` which gives monotonic time. https://docs.python.org/3/library/time.html#time.monotonic – sateesh Mar 08 '19 at 10:00
7
from time import sleep
sleep(0.1) #sleep during 100ms
luc
  • 41,928
  • 25
  • 127
  • 172
3

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 <time.h>
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().

manohar
  • 31
  • 3
  • 1
    So this is where you copied this post? Your example is still abusing threads (both busy spinning and preventing them from running) so the comparison doesn't hold up. When addressing a perceived issue, please define it better than "improper". – Yann Vernier Jun 22 '17 at 08:05
  • As for your proof, it's not sleep that busy waits, it's still your main thread; the routines you wrote just stop *all* Python threads. – Yann Vernier Jun 22 '17 at 08:10
  • Please read http://docs.cython.org/en/latest/src/userguide/external_C_code.html#acquiring-and-releasing-the-gil – Yann Vernier Jun 22 '17 at 08:16
  • My application need was independent sleep operation in each thread – manohar Jun 23 '17 at 09:56
  • Please ignore the main thread, it's a sample code. Or make daemon=False in threads, and remove the infinite loop in the main thread. – manohar Jun 23 '17 at 10:07
  • It's not going to be independent while you're running in the same Python interpreter. The CPython bytecode interpreter holds a lock, so only runs one thread at a time. The sleep duration variance you observed was because of this, and the less variable version was because those other threads are blocked; any thread sleeping with your routine stops *all* Python threads. – Yann Vernier Jun 23 '17 at 10:57
  • Thank you for the reply. But i'm measuring elapsed time using time.time() in every thread, which shows precise delay time with small error in decimals. How this is possible? I'm using Pyrex, not CPython, are both related? – manohar Jun 24 '17 at 12:36
  • Simple: Across the three steps (time 0, sleep, time 1) no other Python thread got to run, because the GIL wasn't released (as time consuming calls normally do). This means that time interval was accurate, but all *other* threads got to wait the same time even though they never asked for it, which is not what you use threads for. The main thread in particular never wanted to wait at all. Normally a sleep specifically leaves time available to other threads. Pyrex and Cython are Python-like compilers for making CPython extensions, so you are using CPython. – Yann Vernier Jun 24 '17 at 15:02
  • Thank you very much for your great help. You are true. I run one thread with my sleep function for 10 sec and in main thread no sleep just printing some count. Along with sleep thread, mian thread also got blocked for 10 sec, which sould not. – manohar Jun 26 '17 at 07:22
  • I'm switching to multiprocessing module which side-steps GIL, instead of threading module. I will edit the test code. I will use subprocesses instead of threads. – manohar Jun 26 '17 at 07:59
  • Updated the test code using multiprocessing. Earlier test logic was also wrong. Actually it was sleeping sequentially thread after thread. Now made the start_time as global to all subprocesses. – manohar Jun 26 '17 at 12:05
  • 2
    Sleep performance improvement of my function is negligible for milli seconds range as compared to python's time.sleep(). Problems was in threads. – manohar Jun 26 '17 at 12:08
2
from time import sleep
sleep(seconds)

More info.

Håvard
  • 9,900
  • 1
  • 41
  • 46
0
from time import sleep

for n in range(0,30000):
    sleep(0.0001)

Since the above run from a linux prompt takes five or six seconds, and not exactly three seconds, I'm not optimistic about doing smaller waits than this 100 microseconds from sleep.

-4

how about this:

import time
def usleep(delay):
   mdelay = delay /1000
   now = time.time()
   while now + mdelay > time.time():
      pass
NoerC
  • 3
  • 4
    You consume 100% CPU until the delay is over? This is what developers did in the MSDOS days, please don't do this on modern multitasking systems. With `time.sleep()` you tell the OS kernel to leave your process in a pause until the timeout is complete, so all other processes can just do their work instead. – vdboor Oct 25 '16 at 08:56
  • 1
    This might consume 100% of the CPU but at least it is far more accurate than sleep. If you have to sleep a lot to keep a timing, e.g. when bitbanging a protocol on a Rapsberry Pi time.sleep() is sometimes WAY of (I am talking about a factor 20!) – Dakkaron Nov 02 '16 at 14:19
  • 3
    By keeping CPU 100% loaded you can actually slow down clock if your clocksource is affected by system load and drop of voltage... Bear that in mind you will lose not only sleeping precision that way – Ajay Nov 10 '16 at 20:39