簡體   English   中英

用C語言處理信號

[英]Signals handling in C

我編寫了以下程序來學習SIG_SETMASK的行為。

下面的程序應該阻塞SIGINT中斷信號,直到func()函數調用

     sigprocmask(SIG_SETMASK,&fOnemask,NULL);

由於fOnemask為空,因為之前沒有信號存儲在sigset中。 但正如我所說

     sigprocmask(SIG_SETMASK,&fTwoCmask,NULL);

返回之前在func2()函數內部,其中fTwomask包含func()函數創建的先前信號列表,程序開始接收信號,並且在傳遞SIGINT時中斷程序。

為什么會這樣呢?

void func();
void func2();

int main()
{
    int childpid,child;
    childpid=fork();

    if(childpid==0)
    {
        func();
    }

    while(wait(NULL)>0);
    return 0;
}

void func()
{
    sigset_t sigmask,fOnemask;
    sigemptyset(&sigmask);
    sigaddset(&sigmask,SIGINT);
    sigprocmask(SIG_SETMASK,&sigmask,&fOnemask);

    func2();

    int i;
    for(i=0;i<10;i++)
    {
        sleep(1);
        printf("%d\n",i);
    }

    sigprocmask(SIG_SETMASK,&omask,NULL);
    printf("returning from func\n");

}

void func2()
{
    sigset_t sigmask,fTwomask;
    sigemptyset(&sigmask);
    sigfillset(&sigmask);
    sigprocmask(SIG_SETMASK,&sigmask,&fTwomask);

    int i;
    for(i=0;i<10;i++)
    {
        sleep(1);
        printf("%d\n",i);
    }

    sigprocmask(SIG_SETMASK,&fTwomask,NULL);
    printf("func2 ending\n");
}

在此處輸入圖片說明

父進程被SIGINT中斷,因為您從未在父進程中為SIGINT設置任何信號處理,因此將其設置為SIG_DFL(可能,除非您在外殼中啟用了中斷處理,這幾乎是不可能的),因此進程終止。

你是對的; 發送中斷時,shell不會死。 那是因為shell非常注意確保它們不會被中斷殺死。


對主要問題的評論之一是:

如果我在main函數的sigset_t對象中添加信號,然后從main調用foo() 然后,我在sigprocmask(SIG_SETMASK, &foomask, &oldmask) foo()foo()本地的另一個sigset_t對象中添加一個信號。 當我調用sigprocmask(SIG_SETMASK, &oldset, NULL)sigprocmask(SIG_SETMASK, &oldset, NULL)做什么?

您的評論(問題)充其量是令人困惑的; 注釋不是編輯問題的最佳方法。

據我了解,您在問:

static void foo(void);

int main(void)
{
    sigset_t mainmask;
    sigemptyset(&mainmask);
    sigaddset(&mainmask, SIGINT);

    // No call to sigprocmask() here...

    foo();
    return(0);
}

static void foo(void)
{
    sigset_t foomask;
    sigset_t oldmask;
    sigset_t oldset;     // Uninitialized
    sigemptyset(&foomask);
    sigaddset(&foomask, SIGQUIT);  // Different signal
    if (sigprocmask(SIG_SETMASK, &foomask, &oldmask) != 0)
        ...process error...
    if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0)
        ...process error...
    ...other code, presumably...
}

這就是評論中寫的內容,據我所知。 而且由於oldset初始化,因此您會遭受GIGO(垃圾進,垃圾出)的困擾; 沒有人可以說會發生什么,因為行為是不確定的。

如果您是在問題中使用oldmask而不是oldset ,則foo()可能看起來像:

static void foo(void)
{
    sigset_t foomask;
    sigset_t oldmask;
    sigemptyset(&foomask);
    sigaddset(&foomask, SIGQUIT);  // Different signal
    if (sigprocmask(SIG_SETMASK, &foomask, &oldmask) != 0)
        ...process error...
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) != 0)
        ...process error...
    ...other code, presumably...
}

然后,第二個sigprocmask()撤消第一次調用sigprocmask()所做的更改。 請記住,SIG_SETMASK選項的意思是“將過程信號掩碼設置為恰好第二個參數中的掩碼”(除非第二個參數為null,在這種情況下,第三個參數不應為null,並且第一個參數是什么都沒有關系參數,因為它變成了在不更改任何內容的情況下找出當前掩碼的調用。

暫無
暫無

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

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