用linux C编程的时候,处理信号在所难免。在多线程编程中需要注意两个函数的使用,一个是pthread_sigmask(), 用来在线程中屏蔽某个信号;另一个是sigaction(),在线程中用来设置信号的处理方式。
void sig_handler1(int arg)
{
printf("thread1 get signal\n");
return;
}
void sig_handler2(int arg)
{
printf("thread2 get signal\n");
return;
}
void *thread_fun1(void *arg)
{
printf("new thread 1\n");
struct sigaction act;
memset(&act, 0, sizeof(act));
sigaddset(&act.sa_mask, SIGQUIT);
act.sa_handler = sig_handler1;
sigaction(SIGQUIT, &act, NULL);
pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
sleep(2);
}
void *thread_fun2(void *arg)
{
printf("new thread 2\n");
struct sigaction act;
memset(&act, 0, sizeof(act));
sigaddset(&act.sa_mask, SIGQUIT);
act.sa_handler = sig_handler2;
sigaction(SIGQUIT, &act, NULL);
// pthread_sigmask(SIG_BLOCK, &act.sa_mask, NULL);
sleep(2);
}
int main()
{
pthread_t tid1, tid2;
int err;
int s;
err = pthread_create(&tid1, NULL, thread_fun1, NULL);
if(err != 0)
{
printf("create new thread 1 failed\n");
return;
}
err = pthread_create(&tid2, NULL, thread_fun2, NULL);
if(err != 0)
{
printf("create new thread 2 failed\n");
return;
}
sleep(1);
s = pthread_kill(tid1, SIGQUIT);
if(s != 0)
{
printf("send signal to thread1 failed\n");
}
s = pthread_kill(tid2, SIGQUIT);
if(s != 0)
{
printf("send signal to thread2 failed\n");
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
结果将会是:
new thread 2
new thread 1
thread1 get signal
或者:
new thread 1
new thread 2
thread2 get signal
会发现sig_handler打印的内容以最后注册的处理函数为准,意思是说线程1和线程2,在线程1中屏蔽SIGQUIT,而线程2中没有,按理来说不管运行多少遍最后处理函数打印出的内容都应该是thread2 get signal。但结果不是这样,为什么??
其实对某个信号处理函数,以程序执行时最后一次注册的处理函数为准,如果线程1最后执行,则以线程1注册的处理函数为准,最后线程2中处理函数替换为了线程1的。即在所有的线程里,同一个信号在任何线程里对该信号的处理一定相同 。