我有一个程序需要为SIGINT使用一个自定义信号处理程序,为SIGCHILD使用一个。
因此,我添加了两个名为sigchildStruct和sigintStruct的struct sigaction,并使用sigaction定义了两个custo信号处理函数:handleSigInt()和handleSigChild()
首先,这是你应该这样做的方式;需要注册两个独立的sigaction结构?
其次,我需要在部分代码执行期间阻止SIGCHILD,我只想在代码中的一个地方接收信号,所以我使用了:
sigdelset(&sigchildStruct.sa_mask,SIGCHLD);
// Catch SIGCHILD signal here
sigaddset(&sigchildStruct.sa_mask,SIGCHLD);
你是怎么做到的?更重要的是:有两个sigaction结构,但我只需要更改其中一个或两者上的sa_mask吗?现在我只更改了名为sigchildStruct的结构上的sa_mask,而不是名为sigintStruct的结构。
其余代码:
void handleSigchild(int sig) {
int childPID,childExitStatus;
printf("\nSIGCHILD received\n");
while ((childPID = waitpid(-1,&childExitStatus,WNOHANG)) >0) {
if (childExitStatus==2) {printf("Background process: %d%s",childPID," terminated by SIGINT\n");}
else if (childExitStatus!=0) {printf("Background process: %d%s",childPID," unknown command\n");}
printf("Background process: %d%s\n",childPID," has exited");
}
}
void handleSigInt(int sig) {
// SIGINT will be sent to all child processes so nothing needs to be done
printf("\nSIGINT received\n");
}
int main(int argc, char ** argv) {
// Sigaction for SIGCHILD
struct sigaction sigchildStruct;
sigchildStruct.sa_handler = &handleSigchild;
sigemptyset(&sigchildStruct.sa_mask);
sigaddset(&sigchildStruct.sa_mask,SIGCHLD);
sigchildStruct.sa_flags = SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sigchildStruct, 0) == -1) {
printf("Couldnt register signal handler: %s\n",strerror(errno));
exit(1);
}
// Sigaction for SIGINT
struct sigaction sigintStruct;
sigintStruct.sa_handler = &handleSigInt;
sigemptyset(&sigintStruct.sa_mask);
sigintStruct.sa_flags = SA_RESTART;
if (sigaction(SIGINT, &sigintStruct, 0) == -1) {
printf("Couldnt register signal handler: %s\n",strerror(errno));
exit(1);
}
sigdelset(&sigchildStruct.sa_mask,SIGCHLD);
// Catch SIGCHILD signal here
sigaddset(&sigchildStruct.sa_mask,SIGCHLD);
}
答案 0 :(得分:0)
因为没有人回答,我会尝试这样做。当我处理信号时,我正在使用函数signal
。该函数有两个参数:信号代码和信号处理函数。为了开始捕捉信号,我会把代码放在:
signal(SIGINT, handleSigInt);
signal(SIGCHILD, handleSigChild);
要停止捕捉信号,我会执行:
signal(SIGINT, SIG_IGN);
signal(SIGCHILD, SIG_IGN);
希望它有所帮助。
答案 1 :(得分:0)
您的代码中存在多个错误。
1)在处理过程中,无需在阻塞信号集中添加SIGCHLD
信号。每个捕获的信号在处理过程中都会被阻塞,因此处理函数不会同时重入:
struct sigaction sigchildStruct;
sigchildStruct.sa_handler = &handleSigchild;
sigemptyset(&sigchildStruct.sa_mask);
// sigaddset(&sigchildStruct.sa_mask,SIGCHLD); // unnecessary
sigchildStruct.sa_flags = SA_NOCLDSTOP;
2)您在设置操作后修改了结构的sa_mask
值,这没有任何效果。如果要阻止信号传递一段时间,则需要修改过程信号掩码。有一个功能:sigprocmask
。所以你可以这样做:
sigset_t oldMask, newMask;
sigemptyset(&newMask);
sigaddset(&newMask,SIGCHLD);
sigprocmask(SIG_BLOCK,&newMask,&oldMask);
// now protected from SIGCHLD delivery, signal will be blocked...
sigprocmask(SIG_SETMASK,&oldMask,NULL);
// old protection reinstalled...