休眠函数与信号映射函数

阅读更多
    下面 3 个函数可以使进程休眠指定的时间(会有所延迟)。
#include 
unsigned 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;
}


    下面几个函数可用于查询信号编号和信号名之间的映射关系。
#include 
void 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。

你可能感兴趣的:(sleep,nanosleep,clock_nanosleep,psignal)