总结:
signal()设置对某种信号的处理方式,只能有一种处理方式,即设置进程、线程的信号handler,对进程、线程都有效。
pthread_kill()可以向线程发送信号。
pthread_sigmask()设置线程的阻塞信号集,但是仅仅对该线程有效。
kill()向进程发送信号,由哪个线程处理该信号是未知的。可能发生的情况是,进程本身屏蔽了该信号,而某个线程没有屏蔽改信号,进而该线程处理了该信号。
示例:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void sig_thread_func(int sig)
{
printf("sig_thread_func : sig = %d\n", sig);
}
void sig_func(int sig)
{
printf("sig_func : sig = %d\n",sig);
}
void *func1(void *arg)
{
signal(SIGUSR1, sig_thread_func); //线程1先运行,设置了signal
sigset_t set;
sigfillset(&set);
sigdelset(&set, SIGUSR1);
pthread_sigmask(SIG_SETMASK, &set, NULL);//线程1屏蔽了除了SIGUSR1外的所有信号
printf("pthread 1 run\n");
int i;
for(i = 0; i < 7; ++i)
{
printf("1...\n");
sleep(1);
}
return 0;
}
void *func2(void *arg)
{
printf("pthread 2 run\n");
int i;
for(i = 0; i < 7; ++i)
{
printf("2...\n");
sleep(1);
}
return 0;
}
int main()
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, func1, NULL);
pthread_create(&tid2, NULL, func2, NULL);
sleep(1);
signal(SIGUSR1, sig_func); //覆盖了线程1设置的signal
//向线程1发送SIGUSR1,SIGUSR2
sleep(1);
pthread_kill(tid1, SIGUSR1);//调动handler
sleep(1);
pthread_kill(tid1, SIGUSR2);//屏蔽了,无响应
//向线程2发送SIGUSR1,SIGUSR2
sleep(1);
pthread_kill(tid2, SIGUSR1);//调用handler
sleep(1);
//pthread_kill(tid2, SIGUSR2);//会终止进程,是进程!
sigset_t set;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);//进程屏蔽了所有信号
sleep(1);
kill(getpid(), SIGUSR1);//调动handler?其实是线程1响应的
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
结果:
pthread 1 run
1...
pthread 2 run
2...
1...
2...
sig_func : sig = 10
1...
2...
1...
2...
sig_func : sig = 10
2...
1...
2...
1...
2...
sig_func : sig = 10
1...
一共对SIGUSR1响应了3次,分别是线程1、2、1响应的。