簡體   English   中英

使用多個自定義信號處理程序在程序中阻止SIGCHILD

[英]Block SIGCHILD in program with multiple custom signal handlers

我有一個程序需要對SIGINT使用一個自定義信號處理程序,對於SIGCHILD使用一個自定義信號處理程序。

因此,我添加了兩個名為sigchildStruct和sigintStruct的結構sigaction,並使用sigaction定義了兩個custo信號處理函數:handleSigInt()和handleSigChild()

首先,這是您應該做的方式嗎? 需要注冊兩個單獨的遷移結構?

第二,我需要在代碼執行的一部分期間阻止SIGCHILD,我只想在代碼中的某個位置接收信號,所以我使用了:

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

那是你會怎么做的? 更重要的是:有兩個Sigaction結構,但我是否只需要更改其中一個或兩個上的sa_mask? 現在,我只在名為sigchildStruct的結構上更改了sa_mask,而不是在名為sigintStruct的結構上更改了sa_mask。

其余代碼:

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 該函數有兩個參數:信號代碼和信號處理程序函數。 要開始捕獲信號,我將輸入代碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM