Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.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
使用多个自定义信号处理程序在程序中阻止SIGCHILD_C - Fatal编程技术网

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

使用多个自定义信号处理程序在程序中阻止SIGCHILD,c,C,我有一个程序,需要为SIGINT和SIGCHILD使用一个自定义信号处理程序 因此,我添加了两个名为sigchildStruct和siginstruct的struct sigaction,并使用sigaction定义了两个custo信号处理函数:handleSigInt()和handleSigChild() 首先,这是你应该做的事情吗;需要注册两个单独的sigaction结构吗 其次,我需要在部分代码执行期间阻止SIGCHILD,我只想在代码中的一个位置接收信号,因此我使用: sigdelset

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

因此,我添加了两个名为sigchildStruct和siginstruct的struct sigaction,并使用sigaction定义了两个custo信号处理函数:handleSigInt()和handleSigChild()

首先,这是你应该做的事情吗;需要注册两个单独的sigaction结构吗

其次,我需要在部分代码执行期间阻止SIGCHILD,我只想在代码中的一个位置接收信号,因此我使用:

sigdelset(&sigchildStruct.sa_mask,SIGCHLD);
// Catch SIGCHILD signal here
sigaddset(&sigchildStruct.sa_mask,SIGCHLD);
你会这样做吗?更重要的是:有两个sigaction结构,但我只需要更改其中一个结构上的sau掩码,还是同时更改这两个结构上的sau掩码?现在我只更改了名为sigchildStruct的结构上的sau掩码,而没有更改名为siginstruct的结构上的sau掩码

代码的其余部分:

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);

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

因为没有人回答,我会尽力回答。当我处理信号时,我使用的是函数
signal
。此函数接受两个参数:信号代码和信号处理函数。要开始捕捉信号,我需要输入以下代码:

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);

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

这将忽略信号,因此如果在此期间触发信号,它将丢失。一般来说,阻塞是一个更好的解决方案。阻塞意味着信号不会丢失,但它的传输将延迟到将来可以控制的某个点。它更好(一般来说),因为如果您安装了处理程序,这是因为您需要知道发生了什么,但忽略恰恰相反;阻塞只会让你延迟回答。