Chinaunix首页 | 论坛 | 博客
  • 博客访问: 993204
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-12-08 12:18:00

10.19 sleep function

#include

 

unsigned int sleep(unsigned int seconds);

 

Returns: 0 or number of unslept seconds

linux 2.4.22里面,这个函数不使用alarm来实现的,用alarm来实现有一个缺点,即他会影响到调用者进程自己预先使用的一些alarm操作。因为一个进程只能有一个有效的alarmlinux它使用了nanosleep来进行精度较高的睡眠,它不使用signal机制。他single unixreal time extension

如下是一个使用alarmsuspend函数来实现的一个较alarmpause函数安全的sleep的实现:

Figure 10.29. Reliable implementation of sleep

#include "apue.h"

 

static void

sig_alrm(int signo)

{

    /* nothing to do, just returning wakes up sigsuspend() */

}

 

unsigned int

sleep(unsigned int nsecs)

{

    struct sigaction    newact, oldact;

    sigset_t            newmask, oldmask, suspmask;

    unsigned int        unslept;

 

    /* set our handler, save previous information */

    newact.sa_handler = sig_alrm;

    sigemptyset(&newact.sa_mask);

    newact.sa_flags = 0;

    sigaction(SIGALRM, &newact, &oldact);

 

    /* block SIGALRM and save current signal mask */

    sigemptyset(&newmask);

    sigaddset(&newmask, SIGALRM);

    sigprocmask(SIG_BLOCK, &newmask, &oldmask);

 

    alarm(nsecs);

 

    suspmask = oldmask;

    sigdelset(&suspmask, SIGALRM);    /* make sure SIGALRM isn't blocked */

    sigsuspend(&suspmask);            /* wait for any signal to be caught */

 

    /* some signal has been caught,   SIGALRM is now blocked */

 

    unslept = alarm(0);

    sigaction(SIGALRM, &oldact, NULL);  /* reset previous action */

 

    /* reset signal mask, which unblocks SIGALRM */

    sigprocmask(SIG_SETMASK, &oldmask, NULL);

    return(unslept);

}

这个实现依然存在一个缺点,它影响了外界的已经存在的alarm。但是它可以取消以前在调用alarm之后,调用pause()之前这段时间如果进程被schedule出去之后,收到了alarm信号的race condition情况,这种情况会造成进程丢失了alarm信号。而使用了alarmsuspend组和,在调用alarm之前,我们将alarm信号block,然后调用suspend,在suspend里面,将alarm信号unblock,当alarm, 所以不会丢失alarm信号,而suspend已被打断,返回到sleep函数里面,alarm又自动的被block

最后,在sleep函数结束前,将alarm 信号的 handler以及signal mask都恢复到系统的默认值。

阅读(600) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~