我有一个主应用程序,它生成一个单独的线程来处理队列中的消息。当我按下CTRL-C时,我在AIX上遇到了一个问题,因为它似乎使线程中的某些“连接句柄”变得无效。我在主程序中有一个关闭钩子来捕获SIGINT但是在AIX上它似乎以某种方式向线程发送信号......虽然这听起来不是我能听到的......
基本上我想知道我是否希望MAIN应用程序处理我感兴趣的所有信号,并且线程/ s永远不会处理任何信号......这是“良好实践”吗?
如果是这样,我怎么能不在线程中使用“sigwait”...实际上我不想在线程中有任何“信号代码”...它们根本就不能接收任何信号。
我清空了所有信号:
sigemptyset(&set);
并设置了SIG_BLOCK
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();
}
如果我只是创建一个线程并且例如在MAIN线程中有SIGINT信号处理程序但是没有为线程设置SIG_BLOCK并且用户命中CTRL-C ....线程是否受到影响所有即使主线程中的信号处理程序运行?这似乎是我在AIX上看到的; - (
感谢您的帮助,非常感谢
林顿
答案 0 :(得分:13)
使用s = pthread_sigmask(SIG_BLOCK, &set, NULL);
,您不会阻止任何内容。
使用:
sigfillset(&set);
sets = pthread_sigmask(SIG_SETMASK, &set, NULL);
如果您想要阻止每个信号,或者如果您正在使用SIG_BLOCK,则明确地将要阻止的信号添加到set
。
创建线程后,需要恢复信号掩码,否则没有线程会捕获任何信号。
然而,看看你之前的问题,可能是捕获信号的线程没有处理被中断的问题。也就是说,如果您被阻止进行系统调用,并且信号到达,则该系统调用将被中止。某些操作系统默认自动再次调用系统调用,有些操作系统会返回错误并将errno设置为应用程序必须处理的EINTR - 如果不处理则可能会发生错误。
相反,使用sigaction()而不是signal()安装信号处理程序,并设置SA_RESTART
标志,这将导致系统调用在信号中止时自动重启。
答案 1 :(得分:-14)
设计仍然错误。 不要使用CTRL + C以受控方式停止应用程序。 使用可通过CORBA,RMI或其他方法访问的正确设计的控制器应用程序与用户交互并控制后台应用程序。
玩得开心......