首页 > 解决方案 > 多线程环境中的信号处理程序行为

问题描述

我有以下程序,其中只有一个线程安装信号处理程序。但是当我通过向每个线程发送信号来测试代码时,所有线程都执行信号处理程序。所有线程是否共享相同的信号处理程序。我假设只有当产生这些线程的主进程安装信号处理程序时才会发生(线程共享信号处理程序)。

还有一个问题是关于信号处理程序执行的上下文。是否保证发送到特定线程的信号将在给定场景的相同线程上下文中执行?

void handler(int signo, siginfo_t *info, void *extra)
{
        printf("handler id %d and thread id %d\n",syscall( SYS_gettid ),pthread_self());
}
void signalHandler()
{
   struct sigaction sa;
   sa.sa_flags = SA_SIGINFO;
   sa.sa_sigaction = handler;
   sigaction(SIGSEGV, &sa, NULL);
   //sigaction(SIGINT, &sa, NULL);
}
void *threadfn0(void *p)
{
        signalHandler();
        printf("thread0\n");
        while ( 1 )
        {
                pause();
        }
}
void *threadfn1(void *p)
{
        while(1){
                printf("thread1\n");
                sleep(15);
        }
        return 0;
}
void *threadfn2(void *p)
{
        while(1){
                printf("thread2\n");
                sleep(15);
        }
        return 0;
}
int main()
{
        pthread_t t0,t1,t2;
        pthread_create(&t0,NULL,threadfn0,NULL);
        printf("T0 is %d\n",t0);
        pthread_create(&t1,NULL,threadfn1,NULL);
        printf("T1 is %d\n",t1);
        pthread_create(&t2,NULL,threadfn2,NULL);
        printf("T2 is %d\n",t2);
        sleep(10);
        pthread_kill(t2,SIGSEGV);
        sleep(10);
        pthread_kill(t1,SIGSEGV);
        pthread_join(t1,NULL);
        pthread_join(t2,NULL);
        pthread_join(t0,NULL);
        return 0;
}

输出:

T0 is 1110239552
T1 is 1088309568
T2 is 1120729408
thread0
thread1
thread2
handler id 18878 and thread id 1120729408
thread2
thread1
handler id 18877 and thread id 1088309568
thread1

标签: clinuxmultithreadingpthreadssignals

解决方案


信号(7)的手册页

信号处置是每个进程的属性:在多线程应用程序中,特定信号的处置对于所有线程都是相同的。

所以所有线程共享相同的处理程序,是的。如果您使用pthread_kill()将信号发送到特定线程,则该线程应执行处理程序(当然,取决于设置为 的线程的信号掩码pthread_sigmask())。

另请注意,您不能printf()在信号处理程序中安全地使用或其他 stdio 函数。请参阅signal-safety(7)中允许的函数列表。


推荐阅读