除此之外我们还可以设置线程自己的信号掩码 , 在前文当中我们已经提到了 , 每个线程都拥有线程自己的掩码 , 因此在下面的程序当中只有线程 2 响应了主线程发送的 SIGTERM 信号 。
#define _GNU_SOURCE#include <stdio.h>#include <pthread.h>#include <unistd.h>#include <signal.h>#include <string.h>void sig(int signo) { char s[1024]; sprintf(s, "signo = %d tid = %d pthread tid = %ld\n", signo, gettid(), pthread_self()); write(STDOUT_FILENO, s, strlen(s));}void* func(void* arg) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGTERM); pthread_sigmask(SIG_BLOCK, &set, NULL); // 上面的代码的功能是阻塞 SIGTERM 这个信号 当这个信号传输过来的时候不会立即执行信号处理函数 // 而是会等到将这个信号变成非阻塞的时候才会响应 printf("func : pthread tid = %ld\n", pthread_self()); for(;;); return NULL;}void* func02(void* arg) { printf("func02 : pthread tid = %ld\n", pthread_self()); for(;;); return NULL;}int main() { signal(SIGTERM, sig); pthread_t t1; pthread_create(&t1, NULL, func, NULL); sleep(1); pthread_t t2; pthread_create(&t2, NULL, func02, NULL); sleep(1); pthread_kill(t1, SIGTERM); pthread_kill(t2, SIGTERM); sleep(2); return 0;}在上面的程序当中我们创建了两个线程并且定义了 SIGTERM 的信号处理函数 , 在线程 1 执行的函数当中修改了自己阻塞的信号集 , 将 SIGTERM 变成了一种阻塞信号 , 也就是说当线程接受到 SIGTERM 的信号的时候不会立即调用 SIGTERM 的信号处理函数 , 只有将这个信号变成非阻塞的时候才能够响应这个信号 , 执行对应的信号处理函数 , 但是线程 t2 并没有阻塞信号 SIGTERM , 因此线程 t2 会执行对应的信号处理函数 , 上面的程序的输出结果如下所示:
func : pthread tid = 139887896323840func02 : pthread tid = 139887887931136signo = 15 tid = 10652 pthread tid = 139887887931136根据上面程序的输出结果我们可以知道线程 t2 确实调用了信号处理函数(根据 pthread tid )可以判断 , 而线程 t1 没有执行信号处理函数 。
在上文当中我们还提到了在一个进程当中 , 所有的线程共享同一套信号处理函数 , 如果在一个线程里面重新定义了一个信号的处理函数 , 那么他将会影响其他的线程 , 比如下面的程序:
#define _GNU_SOURCE#include <stdio.h>#include <pthread.h>#include <unistd.h>#include <signal.h>#include <string.h>void sig(int signo) { char s[1024]; sprintf(s, "signo = %d tid = %d pthread tid = %ld\n", signo, gettid(), pthread_self()); write(STDOUT_FILENO, s, strlen(s));}void sig2(int signo) { char* s = "thread-defined\n"; write(STDOUT_FILENO, s, strlen(s));}void* func(void* arg) { signal(SIGSEGV, sig2); printf("pthread tid = %ld\n", pthread_self()); for(;;); return NULL;}void* func02(void* arg) { printf("pthread tid = %ld\n", pthread_self()); for(;;); return NULL;}int main() { signal(SIGSEGV, sig); pthread_t t; pthread_create(&t, NULL, func, NULL); sleep(1); pthread_t t2; pthread_create(&t2, NULL, func02, NULL); sleep(1); pthread_kill(t2, SIGSEGV); sleep(2); return 0;}
经验总结扩展阅读
- 十二星座是怎样解读爱情的
- 如何理解Java中眼花缭乱的各种并发锁?
- 十二星座中不适合异地恋的星座
- 2023年农历二月二十九出生的男孩命运和五行分析
- 2023年阴历五月初二日是封顶的好日子吗
- 2023年7月29日农历六月十二是乔迁最佳日期吗 2023年7月29日适不适合乔迁
- 2023年农历九月二十六能不能搬家入伙 农历二零二三年九月廿六能不能搬家
- 2023年农历九月二十七吉利吗 今天宜搬入新家吗
- 2023年农历九月二十八可以搬家吗 2023年农历九月二十八搬家怎么样
- 二宁是哪两个省