当一个进程有多个线程的时候,通过kill 命令来给某个进程发送信号的时候,那到底是谁来响应这个信号呢?一定是主线程么?
同时,还要知道信号是可以打断一些阻塞函数的(accept,read ...)
实验:
首先我们使用sigaction函数来注册一个信号处理函数,来响应SIGTERM信号,然后我们创建一个线程,创建线程完毕后,我们在主线程中,使用pthread_sigmask函数来屏蔽SIGTERM信号。当程序跑起来后,我们使用kill 命令来向进程发一个SIGTERM信号,查看是否是子线程来响应该信号的
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <assert.h>
int is_running=1;
void handler(int signo){
is_running=0;
printf("i receive a sig,sig number is %d,threadID is %u\n",signo,(unsigned int)pthread_self());
}
int signal_handler(){
struct sigaction act;
act.sa_flags=0;
sigemptyset(&act.sa_mask);
act.sa_handler=handler;
if(sigaction(SIGTERM,&act,NULL)<0){
return 1;
}
return 0;
}
void* work(void *arg){
int i=0;
printf("thread num is %u\n",(unsigned int)pthread_self());
while(is_running){
//printf("i is %d\n",i);
i++;
}
}
void forbidSig(){
sigset_t block_set;
sigemptyset(&block_set);
sigaddset(&block_set,SIGTERM);
pthread_sigmask(SIG_BLOCK,&block_set,NULL);
}
int main()
{
pthread_t pid;
int ret;
signal_handler();
//forbidSig();
ret=pthread_create(&pid,NULL,work,NULL);
assert(0==ret);
forbidSig();
printf("main thread num is %u\n",(unsigned int)pthread_self());
pthread_join(pid,NULL);
return 0;
}
编译
gcc -g -o test thread.c -lthread
运行
发送信号SIGTERM
查看结果
总结
当我们向某个进程发一个信号的时候,并一定是主线程来响应该信号,如果主线程不方便处理,内核会从所有可以处理该信号的子线程中随机挑选一个来处理该信号。