linux中信号处理第三部分,这部分主要说多线程中的信号处理。
一 多线程有关知识:
首先,线程创建,pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);
几个注意点:
1 新建立的线程函数从start_rtn开始运行,该函数有一个void*型参数,如果需要给start_rtn传递的参数不止一个,则把这些参数放在一个结构体,然后把地址作为arg参数传入。
2 线程创建以后,不能保证哪个线程先运行
然后,线程终止,如果进程当中的某一线程调用了exit, _exit或者_Exit,那么整个进程就会终止。
单个线程退出的三种方式:
1 线程只是从线程函数中返回,
2 线程被统一进程总的其它线程取消
3 线程调用pthread_exit(void *ptr)
二 多线程与信号处理
1 新创建的线程,和所属进程的信号屏蔽字相同,但是每个线程屏蔽字是专属的,不同线程屏蔽字可以不同
2 信号的处理函数是进程中的所有线程共享的,以程序执行时最后注册的处理方式为准。即在一个进程当中,各个线程对信号的处理方式相同。
3 进程的信号是递送到某个线程的,如果信号是与硬件故障或者计时器超时有关,则该信号被发送到引起该事件的线程当中,而其它信号被发送到任意一个线程。
4 要把信号发送给进程,用kill,要把洗脑发送给线程,用pthread_kill。进程用sigprocmask设置信号屏蔽字,线程用pthread_sigmask设置信号屏蔽字。
5 同一进程的不同线程可以设置不同的信号屏蔽字。
由上面第5可知,在多线程当中,可以建立一专门用于处理信号的线程来处理信号中断,其它线程都屏蔽该信号即可。这就是下面说的sigwait的用法。它允许把异步产生的信号用同步的方式处理。在具体的代码实现上可以这样进行设置:
线程创建以前,用
pthread_sigmask屏蔽特定的信号,然后创建线程,这样所建立的所有线程都继承了相同的信号屏蔽字。然后其中一个线程调用saiwait函数,这个函数的第一个参数是信号集,这个信号集当中必须包含上面其它线程都屏蔽的信号。
#include
#include
#include
#include
#define handler_err(msg) \
do{perror(msg); exit(1);}while(0)
int quitflag ;
static void *sig_wait_test(void *arg)
{
int ret, sig;
sigset_t *waitset = (sigset_t*)arg;
while(1)
{
ret = sigwait(waitset, &sig);
if(ret)
{
handler_err("sigwait");
}
switch(sig)
{
case SIGQUIT:printf("got sigquit sig\n"); break;
case SIGINT:printf("got sigint sig\n");break;
default:printf("got other sig\n");break;
}
}
}
int main(void)
{
int ret;
sigset_t set;
pthread_t threadp;
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
sigaddset(&set, SIGINT);
ret = pthread_sigmask(SIG_BLOCK, &set, NULL);
if(ret)
handler_err("pthread_sigmask");
ret = pthread_create(&threadp, NULL, sig_wait_test, &set );
if(ret)
handler_err("pthread_create");
sleep(1000);
printf("exit main function\n");
return 0;
}
执行结果:
按下“ctrl + C”或者“ctrl+\”均没有影响主线程,所有的信号处理都在sig_wait_test线程处理。
阅读(1765) | 评论(0) | 转发(0) |