zeebonk
zeebonk

Reputation: 5044

Is usleep() in C implemented as busy wait?

I'm building a multithreaded application with pthreads and need a thread to periodically check some stuff. During the time in between this thread shouldn't use any CPU. Is this possible with usleep()? Is usleep() not busy waiting? Or is there a better solution?

Upvotes: 18

Views: 36997

Answers (5)

Jens Gustedt
Jens Gustedt

Reputation: 78993

(usleep is not part of the C standard, but of an ancient POSIX standard. But see below.)

No, the POSIX specification of usleep clearly states

The usleep() function will cause the calling thread to be suspended from execution ...

so this clearly requires that it suspends execution and lets the resources to other processes or threads.

As already be mentioned by others, the POSIX function nanosleep is now replacing usleep and you should use that. C (since C11) has a function thrd_sleep that is modeled after nanosleep.

Upvotes: 14

Bill Lynch
Bill Lynch

Reputation: 82026

On Linux, it is implemented with the nanosleep system call which is not a busy wait.

Using strace, I can see that a call to usleep(1) is translated into nanosleep({0, 1000}, NULL).

Upvotes: 6

cnicutar
cnicutar

Reputation: 182764

The function usleep has been removed from SUSv4. You should probably use nanosleep instead or timers (setitimer, etc).

As R.. notes in the comments, should the sleep be implemented as a busy wait:

  • The thread would continue to use the CPU
  • Other (lower-priority) threads wouldn't get a chance to run

Thus:

  • Some might use signals (I think SUSv3 mentioned SIGALARM?)
  • Some might use fancy timers

Upvotes: 16

Brian McFarland
Brian McFarland

Reputation: 9442

Just be aware that both usleep() and nanosleep() can be interrupted by a signal. nanosleep() lets you pass in an extra timespec pointer where the remaining time will be stored if that happens. So if you really need to guarantee your delay times, you'll probably want to write a simple wrapper around nanosleep().

Beware that this is not tested, but something along these lines:

int myNanoSleep(time_t sec, long nanosec)
{
   /* Setup timespec */
   struct timespec req;
   req.tv_sec = sec;
   req.tv_nsec = nanosec;

   /* Loop until we've slept long enough */
   do 
   {
      /* Store remainder back on top of the original required time */
      if( 0 != nanosleep( &req, &req ) )
      {
          /* If any error other than a signal interrupt occurs, return an error */
          if(errno != EINTR)
             return -1; 
      }
      else
      {
          /* nanosleep succeeded, so exit the loop */
          break;
      }
   } while( req.tv_sec > 0 || req.tv_nsec > 0 )
   return 0; /* Return success */
}

And if you ever need to wake the thread for something other than a periodic timeout, take a look at condition variables and pthread_cond_timedwait().

Upvotes: 10

wallyk
wallyk

Reputation: 57804

usleep() is a C runtime library function built upon system timers.
nanosleep() is a system call.

Only MS-DOS, and like ilk, implement the sleep functions as busy waits. Any actual operating system which offers multitasking can easily provide a sleep function as a simple extension of mechanisms for coordinating tasks and processes.

Upvotes: 1

Related Questions