使用多个自定义信号处理程序在程序中阻止 SIGCHILD



我有一个程序,需要为SIGINT使用一个自定义信号处理程序,为SIGCHILD使用一个自定义信号处理程序。

因此,我添加了两个名为 sigchildStruct 和 sigintStruct 的结构 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 receivedn");
    while ((childPID = waitpid(-1,&childExitStatus,WNOHANG)) >0) {
        if (childExitStatus==2) {printf("Background process: %d%s",childPID," terminated by SIGINTn");}
        else if (childExitStatus!=0) {printf("Background process: %d%s",childPID," unknown commandn");}
        printf("Background process: %d%sn",childPID," has exited");
    }
}
void handleSigInt(int sig) {
    // SIGINT will be sent to all child processes so nothing needs to be done
    printf("nSIGINT receivedn");
} 
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: %sn",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: %sn",strerror(errno));
      exit(1);
    }

    sigdelset(&sigchildStruct.sa_mask,SIGCHLD);
    // Catch SIGCHILD signal here
    sigaddset(&sigchildStruct.sa_mask,SIGCHLD);
}

因为没有人回答,我会尝试这样做。当我处理信号时,我正在使用函数signal。此函数采用两个参数:信号代码和信号处理程序函数。要开始捕获信号,我会输入代码:

signal(SIGINT, handleSigInt);
signal(SIGCHILD, handleSigChild);

为了停止捕获信号,我将执行:

signal(SIGINT, SIG_IGN);
signal(SIGCHILD, SIG_IGN);

希望对您有所帮助。

代码中有几个错误。

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...

最新更新