总结:
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响应的。