#includeunsigned int sleep(unsigned int second); /* 返回值:0 或未休眠完的秒数 */ #include int nanosleep(const struct timespec *reqtp, struct timespec *remtp); /* 返回值:若休眠到要求的时间,返回 0;若出错,返回 -1 */ int clock_nanosleep(clockid_t clock_id,int flags,const struct timespec *reqtp,struct timespec *remtp); /* 返回值:若休眠到要求的时间,返回 0;若出错,返回 错误码 */
sleep 函数使进程挂起直到经过 seconds 秒或调用进程捕捉到一个信号并从信号处理程序返回。
nanosleep 函数与 sleep 类似,但提供了纳秒级的精度。reqtp 参数用秒和纳秒指定了需要休眠的时间长度,remtp 参数则代表未休眠完的时间长度,如果不感兴趣可将其置为 NULL。nanosleep 函数并不涉及产生任何信号,所以不需要担心与其他函数的交互。
clock_nanosleep 函数使用相对于特定时钟的延迟时间来挂起调用线程。clock_id 参数指定了计算延迟时间基于的时钟。flags 参数用于控制延迟是相对的(设置为 0 时)还是绝对的(设置为 TIMER_ABSTIME 时)。reqtp 和 remtp 同 nanosleep 函数。不过使用绝对时间时,remtp 参数未使用,因为没必要。在时钟到达指定的绝对时间值以前,可以为其他的 clock_nanosleep 调用复用 reqtp 参数相同的值。
下面程序是 POSIX.1 sleep 函数的一种实现,它可靠地处理信号,避免了早期实现中的竞争条件,但是仍未处理与以前设置的闹钟的交互作用(POSIX.1 并未显示地对这些交互进行定义)。
#include#include static void sig_alrm(int signo){ ; // nothing to do, just returning wakes up sigsuspend(). } unsigned int sleep(unsigned int seconds){ unsigned int unslept; struct sigaction act, oldact; sigset_t newmask, oldmask, susmask; /* set handler, save previous information */ act.sa_handler = sig_alrm; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, &oldact); /* block SIGALRM and save current signal mask */ sigemptyset(&newmask); sigaddset(&newmask, SIGALRM); sigprocmask(SIG_BLOCK, &newmask, &oldmask); alarm(seconds); susmask = oldmask; sigdelset(&susmask, SIGALRM); // make sure SIGALRM isn't blocked sigsuspend(susmask); // wait for any signal to be caught /* some signal has been caught, SIGALRM is now blocked */ unslept = alarm(0); /* reset previous action */ sigaction(SIGALRM, &oldact, NULL); /* reset signal mask, which unblocks SIGALRM */ sigprocmask(SIG_SETMASK, &oldmask, NULL); return unslept; }
下面几个函数可用于查询信号编号和信号名之间的映射关系。
#includevoid psignal(int signo, const char *msg); void psiginfo(const siginfo_t *info, const char *msg); #include char *strsignal(int signo); /* 返回值:指向描述该信号的字符串的指针 */ // Solaris 提供的 #include int sig2str(int signo, char *str); int str2sig(const char *str, int *signop); /* 返回值:若成功,都返回 0;否则,都返回 -1 */
psignal 函数可移植地打印与信号编号对应的字符串。参数 msg(通常是程序名)输出到标准错误文件,后面跟着一个冒号和一个空格,再是该信号的说明,最后是一个换行符。如果 msg 是 NULL,则只有信号说明部分输出到标准错误文件,类似于 perror。
如果在 sigaction 信号处理程序中有 siginfo 结构,则可以使用 psiginfo 函数打印信号信息。它与 psignal 函数类似,不过可以访问除信号编号以外的更多信息,但不同的平台输出的这些额外信息可能有所不同。
如果只需要信号的字符描述部分,也不需要把它写到标准错误文件中(如可以写到日志文件中),就可以使用 strsignal 函数,它类似于 strerror。
sig2str 和 str2sig 函数是 Solaris 提供的。sig2str 将给定的信号编号翻译成字符串存放在 str 所指向的存储区,它会去掉信号名中的“SIG”前缀。str2sig 则将给出的信号名翻译成信号编号存放在 signop 指向的整型中,该名字要么是不带“SIG”前缀的信号名,要么是表示十进制信号编号的字符串(如“9”)。注意,这两个函数失败时都不会设置 errno。