除此之外我们还可以设置线程自己的信号掩码,在前文当中我们已经提到了 , 每个线程都拥有线程自己的掩码,因此在下面的程序当中只有线程 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;}上面的程序的输出结果如下所示:
pthread tid = 140581246330624pthread tid = 140581237937920thread-defined从上面程序输出的结果我们可以看到线程 t2 执行的信号处理函数是 sig2 而这个信号处理函数是在线程 t1 执行的函数 func 当中进行修改的,可以看到线程 t1 修改的结果确实得到了响应 , 从这一点也可以看出,如果一个线程修改信号处理函数是会影响到其他的线程的 。
推荐阅读
- 如何理解Java中眼花缭乱的各种并发锁?
- 百变大侦探三男二女剧本杀真相答案详解
- 十五二十猜拳怎么玩啊
- 十五二十猜拳怎么玩
- 抓包整理————ip 协议一[十二]
- 天涯明月刀怎么导入捏脸数据(天刀手游捏脸二维码图)
- Mysql InnoDB多版本并发控制MVCC
- C#多线程之线程基础篇
- 二十四 设计模式学习:Spring 中使用到的设计模式
- <二>掌握构造函数和析构函数