使用SIGALRM实现sleep()

时间:2014-01-02 10:36:43

标签: c signals

我试图用SIGALRM取代sleep()。

#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*/
}

这是正确的实施吗? 还有其他实现吗?

3 个答案:

答案 0 :(得分:0)

真正的实现必须处理更多条件:

  1. 处理EINTR
  2. 处理线程取消。
  3. 请参阅glibc implementatiop of sleep()

答案 1 :(得分:0)

SIGALARM实现非常遗留,并且不符合现代标准(尤其是,因为如果从库中调用它,您将会混淆应用程序可能正在使用的任何警报)。所以它需要另一个系统调用。

可能的选择:

  • 使用nanosleep。这是大多数内核的系统调用 - 它只是sleep的高分辨率版本,所以你的工作也是如此。请注意,如果忽略SIGCHLD,sleep会有一些垃圾行为,因此glibc实现会阻止并解除阻塞nanosleep - sleep实现的信号,以尝试获取遗留行为!< / LI>
  • 使用select。这是一个非常好的选择 - 使用空的FD_SET并传递你的超时。非常便携,没有任何问题。

答案 2 :(得分:-1)

您的实现只是模仿sleep()函数。但实际的内部实现依赖于操作系统。一个简单的实现可以如下:

操作系统将进程与时间戳一起放在wait queue中,之后必须再次执行。每当时间到来时,它都会返回ready queue并开始执行该过程。您还可以参考here了解更多信息。