Question

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
Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

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.

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top