Matt Dunn
Matt Dunn

Reputation: 5420

Effect of usleep(0) in C++ on Linux

The documentation for usleep states that calling usleep(0) has no effect. However, on my system (RHEL 5.2) running the small snippets of C++ code below, I find that it actually appears to have the same effect as usleep(1). Is this to be expected, and if so, why is there the discrepancy between the documentation and what I see in real life?

Exhibit A

Code:

#include <unistd.h>

int main()
{
    for( int i = 0; i < 10000; i++ )
    {
        usleep(1);
    }
}

Output:

$ time ./test
real   0m10.124s
user   0m0.001s
sys    0m0.000s

Exhibit B

Code:

#include <unistd.h>

int main()
{
    for( int i = 0; i < 10000; i++ )
    {
        usleep(1);
        usleep(0);
    }
}

Output:

$ time ./test
real   0m20.770s
user   0m0.002s
sys    0m0.001s

Upvotes: 11

Views: 23676

Answers (8)

liqiang2020
liqiang2020

Reputation: 1

Both usleep(1) and usleep(0) need to make system calls and undergo two scheduling (the first time is to be deprived of the CPU, and the second time to regain the CPU). For such a process, it is generally greater than 1us.

The kernel timer will re-awaken your test program exactly after 0us and 1us. At this time, your test program may even be completing the first context switch? So for your test program, one usleep(0) and one usleep(1) take the same time.

Upvotes: 0

Peng Zhang
Peng Zhang

Reputation: 3595

usleep() and sleep() are translated to nanosleep() system calls. Try strace your program and you'll see it. From nanosleep() manual:

   nanosleep() suspends the execution of the calling thread until either
   at least the time specified in *req has elapsed, or the delivery of a
   signal that triggers the invocation of a handler in the calling
   thread or that terminates the process.

So I think ulseep(0) will generate an interrupt and a context switch.

Upvotes: 2

HAL9000
HAL9000

Reputation: 3761

As of my experience it has one effect: it's calling an interrupt.
This is good to release the processor for the smallest amount of time in multithreading programming.

Upvotes: 0

niloydebnath
niloydebnath

Reputation: 91

I just wanted to point out about the time command used here. You should use /usr/bin/time instead of only time command if you want to check your program memory,cpu,time stat. When you call time without full path then built-in time command is called. Look at the difference.

without full path:

# time -v ./a.out
-bash: -v: command not found

real    0m0.001s
user    0m0.000s
sys     0m0.001s

with full path:

# /usr/bin/time -v ./a.out
Command being timed: "./a.out"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:10.87
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 220
Voluntary context switches: 10001
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

use man time for /usr/bin/time manual and use help time for built in time information.

Upvotes: 5

happycube
happycube

Reputation: 31

It also depends on if udelay is implemented as a busy loop for short durations.

Upvotes: 1

Gearoid Murphy
Gearoid Murphy

Reputation: 12126

That documentation is back from 1997, not sure if it applies to current RHEL5, my Redhat dev systems man page for usleep does not indicate that a sleep time of 0 has no effect.

The parameter you pass is a minimum time for sleeping. There's no guarantee that the thread will wake up after exactly the time specified. Given the specific dynamics of the scheduler, it may result in longer than expected delays.

Upvotes: 2

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799490

Technically it should have no effect. But you must remember that the value passed is used as a minimum, and not an absolute, therefore the system is free to use the smallest possible interval instead.

Upvotes: 14

twalberg
twalberg

Reputation: 62519

I would have to look at the source to make sure, but my guess is that it's not quite "no effect", but it's probably still less than usleep(1) - there's still the function call overhead, which can be measurable in a tight loop, even if the library call simply checks its arguments and returns immediately, avoiding the more usual process of setting up a timer/callback and calling the scheduler.

Upvotes: 3

Related Questions