简体   繁体   中英

Implementing sleep() using SIGALRM

I have tried to replace sleep() by SIGALRM.

#include <signal.h> 
#include <unistd.h>

void sig_alrm( int signo )
{
    return; /* return to wake up pause */
}

unsigned int sleep1( unsigned int nsecs )
{
    if( signal( SIGALRM, sig_alrm ) == SIG_ERR )
        return (nsecs);
    alarm( nsecs ); /* starts timer */
    pause(); /* next caught signal wakes */
    return( alarm( 0 ) ); /* turn off timer, return unslept*/
}

Is this correct implementation? Is there another implementation?

The real implementation has to handle more conditions:

  1. Handle EINTR .
  2. Handle thread cancellation.

See glibc implementatiop of sleep() .

The SIGALARM implementation is seriously legacy, and won't conform modern standards (not least, because if you call it from a library you'll mess with any alarms the application may be using). So it needs another syscall.

Possible choices:

  • Use nanosleep . It's a syscall on most kernels - it's just a high resolution version of sleep , so does the job for you. Note that sleep has some junky behaviour if SIGCHLD is ignored, so the glibc implementation blocks and unblocks the signals in its nanosleep -wrapping implementation of sleep to try and get the legacy behaviour!
  • Use select . It's a perfectly good choice - use empty FD_SETs and pass in your timeout. Very portable and there's nothing wrong with it.

Your implementation just mimics the sleep() function. But the actual internal implementation is OS-dependent. One simple implementation can be as follows:

The OS puts the process in the wait queue along with the time stamp after which it must be executed again. Whenever the time comes, it brings back to the ready queue and starts executing the process. You can also refer here for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM