#include <signal.h>
int sigsuspend(const sigset_t *mask);
sigsuspend函数是等待某个信号到达,然后调用处理函数之后才返回的,否则会处于阻塞等待状态。unix环境高级编程的sleep函数就是通过alarm函数和sigsuspend函数来实现的。
但是当我自己写了一个程序的时候,线程调用unix环境高级编程实现的sleep函数竟然老是一睡不醒,调试发现原来sigsuspend函数不可以用在新建线程,而用在控制线程或者进程就行。代码如下:
void sig_print(int signo)
{
printf("alarm signo\n");
}
void test_suspend()
{
sigset_t newmask;
sigprocmask(SIG_BLOCK,NULL ,&newmask);
sigdelset(&newmask, SIGALRM);
signal(SIGALRM,sig_print);//SIGALRM信号处理函数绑定
alarm(2); //2秒后产生SIGALRM信号
sigsuspend(&newmask); //等待SIGALRM信号的到来
printf("sigsuspend return\n");
}
现在在线程调用这个函数:
pthread_t tid1;
void *
thr_fn1(void *arg)
{
printf("thread 1 returning\n");
test_suspend();
return ((void *)1);
}
int
main(void)
{
int err;
void *tret;
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
while(1);
}
运行结果:[root@localhost threads]# ./exitstatus thread 1 returningalarm signo
表明线程运行,调用test_sigsuspend函数,在该函数里启动2s定时,并在sigsuspend函数阻塞。时间到调用SIGALRM信号处理函数,但是sigsuspend函数没有返回(没有打印sigsuspend return),这样线程就一直堵住不动。
如果把test_sigsuspend函数搬到主线程
int
main(void)
{
int err;
void *tret;
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
test_suspend();
while(1);
}
[root@localhost threads]# ./exitstatus
thread 1 returning
alarm signo
sigsuspend return
对于新建线程要达到sigsuspend函数的效果,就是使用sigwait函数,代码:
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
pthread_t tid1, tid2;
sigset_t mask;
void sig_print(int signo)
{
printf("alarm signo\n");
}
void test_sigwait()
{
int signal;
alarm(2); //2s后发送SIGALRM信号
sigwait(&mask,&signal); //阻塞等待SIGALRM信号
printf("sigwait return\n");
switch(signal)
{
case SIGALRM:
sig_print(0);
}
}
void *
thr_fn1(void *arg)
{
printf("thread 1 returning\n");
test_sigwait(); //调用sigwait函数
return ((void *)1);
}
int
main(void)
{
int err;
void *tret;
sigaddset(&mask,SIGALRM);
pthread_sigmask(SIG_BLOCK,&mask,NULL);
err = pthread_create(&tid1, NULL, thr_fn1, NULL);
while(10);
}
运行结果:
[root@localhost threads]# ./exitstatus
thread 1 returning
sigwait return
alarm signo
结论:sigsuspend函数用于线程或者主线程,sigwait函数用于新建线程。