多线程编程信号处理顺序

来源:互联网 发布:淘宝卖家怎么改运费 编辑:程序博客网 时间:2024/06/05 10:34

线程可以使用sigwait来对信号进行处理。

但是如果主线程中已经用sig_handler注册了处理函数,子线程里同时也用sigwait来处理信号,那么谁会先处理呢?APUE上只是写了一下依赖于操作系统,这里我们来做实验,看看linux中哪个会处理。

#include <pthread.h>#include <signal.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdio.h>int quitflag;sigset_t mask;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t wait = PTHREAD_COND_INITIALIZER;void * thr_fn(void * arg){#if 1int err, signo;sigset_t oldmask;sigemptyset(&mask);sigaddset(&mask, SIGINT);sigaddset(&mask, SIGQUIT);sigaddset(&mask, SIGBUS);if((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0){printf("SIGBLOCK error\n");exit(err);}for(;;){err = sigwait(&mask, &signo);if(0 !=  err){printf("sigwait failed\n");exit(err);}switch(signo){case SIGBUS:printf("SIGBUS\n");break;default:printf("unexpected signal %d\n",signo);exit(1);}}out0:if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){printf("SIG_SETMASK error\n");exit(err);}#endifexit(0);}static void sigbus_handler(void* data){printf("SIGBUG: sigbus_handler \n");return;}static void qemu_init_sigbus(void){    struct sigaction action;    memset(&action, 0, sizeof(action));    action.sa_flags = SA_SIGINFO;    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;    sigaction(SIGBUS, &action, NULL);}int main(void){int err;pthread_t tid;qemu_init_sigbus();err = pthread_create(&tid,NULL,thr_fn,0);if(err != 0){printf("can not create thread\n");exit(err);}exit(0);}


编译代码

gcc test.c -o test -lpthread


运行结果

./test 

kill -7 ${主线程PID}
SIGBUG: sigbus_handler 

kill -7 ${子线程PID}

SIGBUG


从而可以看到,如果子线程中有写了sigwait的处理函数,那么sigwait处理,主线程是sig_handler处理


在做个试验

#include <pthread.h>#include <signal.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdio.h>int quitflag;sigset_t mask;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t wait = PTHREAD_COND_INITIALIZER;void * thr_fn(void * arg){for(;;){sleep(5);}exit(0);}#if 1static void sigbus_handler(void* data){printf("SIGBUG: sigbus_handler \n");return;}static void qemu_init_sigbus(void){    struct sigaction action;    memset(&action, 0, sizeof(action));    action.sa_flags = SA_SIGINFO;    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;    sigaction(SIGBUS, &action, NULL);}#endifint main(void){int err;pthread_t tid;qemu_init_sigbus();err = pthread_create(&tid,NULL,thr_fn,0);if(err != 0){printf("can not create thread\n");exit(err);}pthread_mutex_lock(&lock);while(quitflag == 0){pthread_cond_wait(&wait, &lock);}pthread_mutex_unlock(&lock);quitflag = 0;exit(0);}

运行结果

./test 


kill -7 ${主线程PID}
SIGBUG: sigbus_handler 

kill -7 ${子线程PID}

SIGBUG: sigbus_handler 

子线程中没有响应的信号处理函数,那么系统会统一选用主进程中的信号处理函sig_handler数进行处理


综上所述


Linux内核没有做特殊处理的情况下:

如果子线程中有写了sigwait的处理函数,那么sigwait处理,主线程是sig_handler处理

子线程中没有响应的信号处理函数,那么系统会统一选用主进程中的信号处理函sig_handler数进行处理








0 0
原创粉丝点击