休眠函数与信号映射函数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/aisxyz/article/details/84910254
下面 3 个函数可以使进程休眠指定的时间(会有所延迟)。

#include <unistd.h>
unsigned int sleep(unsigned int second); /* 返回值:0 或未休眠完的秒数 */
#include <time.h>
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 <unistd.h>
#include <signal.h>

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;
}


下面几个函数可用于查询信号编号和信号名之间的映射关系。

#include <signal.h>
void psignal(int signo, const char *msg);
void psiginfo(const siginfo_t *info, const char *msg);
#include <string.h>
char *strsignal(int signo); /* 返回值:指向描述该信号的字符串的指针 */

// Solaris 提供的
#include <signal.h>
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。
展开阅读全文

没有更多推荐了,返回首页