我有以下程序,其中只有一个线程安装信号处理程序。但是,当我通过向每个线程发送信号来测试代码时,所有线程都会执行信号处理程序。是否所有线程共享相同的信号处理程序。我以为只有在产生这些线程的主进程安装了信号处理程序时,它才会发生(线程共享信号处理程序)。
还有另一个问题是关于信号处理程序执行的上下文。是否可以确保发送给特定线程的信号将在给定场景下在相同的线程上下文中执行?
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
信号处置是每个进程的属性:在多线程应用程序中,特定信号的处置对于所有线程都是相同的。
所以所有线程共享相同的处理程序,是的。如果使用pthread_kill()
向特定线程发送信号,则该线程应执行处理程序(当然,取决于pthread_sigmask()
设置的线程信号掩码)。
也请注意,您不能在信号处理程序中安全地使用pthread_sigmask()
或其他stdio函数。请参见printf()
中允许的功能列表。
所有线程共享信号处理程序。您可以使用pthread_sigmask()来选择哪些线程具有哪些信号被阻塞或解除阻塞,因此可以执行该处理程序。如果多个线程具有相同的信号不受阻塞,则它们中的任何一个都可以执行处理程序。
因此清理并修复的示例如下所示:
signal-safety(7)