如何在不使用SIGWAIT的情况下阻止线程中的所有SIGNALS?

Lyn*_*ice 10 c unix signals pthreads

我有一个主应用程序,它生成一个单独的线程来处理队列中的消息.当我按下CTRL-C时,我在AIX上遇到了一个问题,因为它似乎使线程中的某些"连接句柄"变得无效.我在主程序中有一个关闭钩子来捕获SIGINT但在AIX上它似乎以某种方式向线程发送信号......虽然这听起来不太可能......

基本上我想知道我是否希望MAIN应用程序处理我感兴趣的所有信号,并且线程/ s永远不会处理任何信号......这是"良好实践"吗?

如果是的话我怎么就不能使用"调用sigwait"中的线程...其实我也不想在线程/ s的任何"信号代码" ......他们必须简单地根本不接收任何信号.

我清空了所有的信号:

sigemptyset(&set);
Run Code Online (Sandbox Code Playgroud)

并设置了SIG_BLOCK

s = pthread_sigmask(SIG_BLOCK, &set, NULL);
Run Code Online (Sandbox Code Playgroud)

所以这是一个虚拟测试程序:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

#define handle_error_en(en, msg) do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void * threadMainLoop(){
    //Here I do not want the thread to use "sigwait"....
    while(running == TRUE){
      //do some thread work and never have any signals come in
    }
}

void shutdownHook(int sig){
    printf("\nCtrl-C pressed....shutdown hook in main...\n");
}

void signalErrorHandler(int signum){
    printf("\nSignal error handler in main...\n");
}

int main(int argc, char *argv[]){
    pthread_t thread;
    sigset_t set;
    int s;

    //Catch the following signals in the MAIN thread
    (void) signal(SIGINT, shutdownHook);
    (void) signal(SIGSEGV, signalErrorHandler);
    (void) signal(SIGBUS, signalErrorHandler);
    (void) signal(SIGILL, signalErrorHandler);
    (void) signal(SIGTERM, signalErrorHandler);
    (void) signal(SIGABRT, signalErrorHandler);

    sigemptyset(&set); //BLOCK all signals

    s = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_sigmask");

    s = pthread_create(&thread, NULL, &threadMainLoop, (void *) NULL);
    if (s != 0)
        handle_error_en(s, "pthread_create");  

    pause();
}
Run Code Online (Sandbox Code Playgroud)

如果我只是创建一个线程,并有,例如,在主线程SIGINT信号的处理程序,但不要有SIG_BLOCK为线程设置和用户点击CTRL-C ....没有线程得到任何影响,即使主线程中的信号处理程序运行?这似乎是我在AIX上看到的;-(

感谢您的帮助,非常感谢

林顿

nos*_*nos 15

s = pthread_sigmask(SIG_BLOCK, &set, NULL);,你没有阻止任何事情.

使用:

sigfillset(&set);
sets = pthread_sigmask(SIG_SETMASK, &set, NULL);
Run Code Online (Sandbox Code Playgroud)

如果要阻止每个信号,或者set如果您正在使用SIG_BLOCK ,则显式添加要阻止的信号.

创建线程后,需要恢复信号掩码,否则没有线程会捕获任何信号.

但是,看看你之前的问题,可能是捕获信号的线程无法处理中断.也就是说,如果您被阻止进行系统调用,并且信号到达,则该系统调用将被中止.某些操作系统默认会再次自动调用系统调用,有些会返回错误并将errno设置为应用程序必须处理的EINTR - 如果不处理则可能会发生错误.

相反,使用sigaction()而不是signal()安装信号处理程序,并设置SA_RESTART标志,这将导致系统调用在信号中止时自动重启.