Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在不使用SIGWAIT的情况下阻止线程中的所有信号?_C_Unix_Pthreads_Signals - Fatal编程技术网

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

C 如何在不使用SIGWAIT的情况下阻止线程中的所有信号?,c,unix,pthreads,signals,C,Unix,Pthreads,Signals,我有一个主应用程序,它生成一个单独的线程来处理队列中的消息。当我点击CTRL-C时,我在AIX上遇到了一个问题,因为它似乎使线程中的一些“连接句柄”变得无效。我在主程序中确实有一个捕获SIGINT的shutdownhook,但在AIX上,它似乎也会以某种方式向线程发送一个信号……尽管从我听到的情况来看,这实际上是不可能的 本质上,我想知道我是否希望主应用程序处理我感兴趣的所有信号,并且让线程从不处理任何信号……这是“良好实践”吗 如果是这样的话,我怎么能不在线程中使用“sigwait”…事实上,

我有一个主应用程序,它生成一个单独的线程来处理队列中的消息。当我点击CTRL-C时,我在AIX上遇到了一个问题,因为它似乎使线程中的一些“连接句柄”变得无效。我在主程序中确实有一个捕获SIGINT的shutdownhook,但在AIX上,它似乎也会以某种方式向线程发送一个信号……尽管从我听到的情况来看,这实际上是不可能的

本质上,我想知道我是否希望主应用程序处理我感兴趣的所有信号,并且让线程从不处理任何信号……这是“良好实践”吗

如果是这样的话,我怎么能不在线程中使用“sigwait”…事实上,我不想在线程中使用任何“信号代码”…它们必须根本不接收任何信号

我已经清空了所有的信号:

sigemptyset(&set);
并设置了SIG_块

s = pthread_sigmask(SIG_BLOCK, &set, NULL);
下面是一个虚拟测试程序:

#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();
}
#包括
#包括
#包括
#包括
#包括
#包括
#在(0)时定义句柄_error_en(en,msg)do{errno=en;perror(msg);exit(exit_FAILURE);}
静态void*threadMainLoop(){
//这里我不希望线程使用“sigwait”。。。。
while(running==TRUE){
//做一些线程工作,永远不要有任何信号进来
}
}
无效关闭吊钩(内部信号){
printf(“\nCtrl-C按下…主…中的关机挂钩…\n”);
}
无效信号错误处理程序(int signum){
printf(“\n主文件中的信号错误处理程序…\n”);
}
int main(int argc,char*argv[]){
pthread\u t线程;
sigset\u t集;
int-s;
//在主线程中捕获以下信号
(无效)信号(SIGINT、停机钩);
(无效)信号(SIGSEGV,signalErrorHandler);
(无效)信号(SIGBUS,signalErrorHandler);
(无效)信号(SIGILL,signalErrorHandler);
(无效)信号(SIGTERM,signalErrorHandler);
(无效)信号(SIGABRT,signalErrorHandler);
SIGEPTYSET(&set);//阻止所有信号
s=pthread_sigmask(SIG_块,&set,NULL);
如果(s!=0)
handle_error_en(s,“pthread_sigmask”);
s=pthread_create(&thread,NULL,&threadMainLoop,(void*)NULL);
如果(s!=0)
handle_error_en(s,“pthread_create”);
暂停();
}
例如,如果我只是创建一个线程,并且在主线程中有SIGINT信号处理程序,但没有为线程设置SIG_块,并且用户点击CTRL-C…。即使主线程中的信号处理程序运行,线程是否会受到影响?这似乎就是我在AIX上看到的情况-(

谢谢你的帮助,非常感谢


Lynton

使用
s=pthread\u sigmask(SIG\u BLOCK,&set,NULL);
,您不会阻止任何东西

使用:

如果要阻止每个信号,或者如果使用SIG_块,则将要阻止的信号显式添加到
集合

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

但是,看看前面的问题,捕获信号的线程可能不会处理被中断的问题。也就是说,如果您在执行系统调用时被阻止,并且信号到达,那么该系统调用将被中止。一些操作系统默认为再次自动调用系统调用,一些操作系统返回错误并将errno设置为EINTR,而ch应用程序必须处理—如果不处理,可能会发生不好的事情

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

设计仍然错误。 不要使用CTRL+C以受控方式停止应用程序。 使用一个设计正确的控制器应用程序,可以通过CORBA、RMI或其他方法访问该应用程序,以与用户交互并控制后台应用程序


大家玩得开心…

大家好,但如果我设置了“s=pthread_sigmask(SIG_BLOCK,&set,NULL);”并使用CTRL-C测试线程是否没有接收到信号?这意味着它正在阻止它?如果我添加了“sigaddset(&set,SIGINT);”则线程会接收到信号。如果我在这里出错,请原谅我…我仍在学习…-)谢谢帮助;-)更新了一点答案。。信号屏蔽是指无法提升的信号。因此,如果您执行sigaddset(&set,SIGINT);pthread_sigmask(SIG_BLOCK,&set,NULL),SIGINT将在SIGNAL掩码中设置,这意味着线程将不会接收它。如果创建新线程,该线程将从创建它的线程继承信号掩码。请注意,如果希望新线程以屏蔽信号开始(通常是避免恶劣竞争条件所必需的)在调用
pthread\u create
之前需要阻止信号,然后在
pthread\u create
返回后在原始线程中恢复旧的信号掩码。@LyntonGrice,当阻止信号并将其发送到线程时,该信号仍然挂起到线程。当您稍后取消阻止线程时,信号将被传递。如果你不希望信号传递,你必须忽略它,而不是阻止它。
sigfillset(&set);
sets = pthread_sigmask(SIG_SETMASK, &set, NULL);