1

の振る舞いを学ぶために以下のプログラムを作成しました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");
}

ここに画像の説明を入力してください

4

1 に答える 1

0

親プロセスでSIGINTのシグナル処理を設定したことがないため、親プロセスはSIGINTによって中断されます。したがって、SIG_DFLに設定されます(おそらく、シェルで割り込み処理をオフにした場合を除きます。これはほとんどありません)。プロセスは終了します。

あなたが正しい; 割り込みが送信されても​​シェルは死にません。これは、シェルが割り込みによって殺されないように細心の注意を払っているためです。


主な質問に対するコメントの1つは次のとおりです。

sigset_t関数内のオブジェクトにシグナルを追加してから、からmain呼び出す場合。次に、 likeにローカルな別のオブジェクトにシグナルを追加します。電話するとどうなりますか?foo()mainsigset_tfoo()sigprocmask(SIG_SETMASK, &foomask, &oldmask)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代わりに意味する場合は、次のようになります。oldsetfoo()

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

次に、2番目sigprocmask()はへの最初の呼び出しによって行われた変更を元に戻しますsigprocmask()。SIG_SETMASKオプションは、「プロセスシグナルマスクを2番目の引数のマスクに正確に設定する」ことを意味することを忘れないでください(2番目の引数がnullでない限り、3番目の引数はnullであってはならず、最初の引数が何であるかは関係ありません。何も変更せずに現在のマスクを見つけるための呼び出しになるため、引数)。

于 2013-01-06T17:11:10.320 に答える