C语言中的信号处理

C语言中的信号处理,c,unix,signals,interrupt-handling,C,Unix,Signals,Interrupt Handling,我制作了以下程序来学习SIG_SETMASK的行为 下面的程序应该在func函数调用之前阻止SIGINT中断信号 sigprocmask(SIG_SETMASK,&fOnemask,NULL); 因为fOnemask是空的,所以在它之前的sigset中没有存储任何信号。但正如我所说 sigprocmask(SIG_SETMASK,&fTwoCmask,NULL); 在返回之前的func2函数内部,其中fTwomask包含func函数生成的上一个信号列表,程

我制作了以下程序来学习SIG_SETMASK的行为

下面的程序应该在func函数调用之前阻止SIGINT中断信号

     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不会消亡。这是因为shell非常小心地确保它们不会被中断杀死

对主要问题的评论之一是:

如果我在main函数的sigset_t对象中添加一个信号,然后从main调用foo。然后,我在foo本地的另一个sigset_t对象中添加一个信号,比如sigprocmaskSIG_SETMASK、&foomask、&oldsmask。当我调用sigprocmaskSIG_SETMASK,&oldset,NULL时,sigprocmaskSIG_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垃圾输入、垃圾输出的痛苦;没有人能说出发生了什么,因为行为是未定义的

如果您在问题中的意思是oldsmask而不是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,并且与第一个参数中的内容无关,因为它变成了一个在不更改任何内容的情况下查找当前掩码的调用。

您的示例存在一个问题:它从不调用func。请更新代码,并尝试保留缩进以再现您的问题。用对func的调用替换main,不使用fork,工作正常,sigint保持阻塞状态。func2中的sigprocmask何时返回fTwomask i-e中的旧信号列表;func创建的列表。我不理解你的评论。我将重复上面所说的:您发布的代码从不调用func或func2。请把你玩的确切代码贴出来。我更新了问题。它在发布代码时被删除。注意,在func2中对SIGEPTYESET和sigfillset的连续调用是多余的;在上下文中,只调用sigfillset。当前子进程正在运行时,父进程如何死亡?很容易…非常容易。想想守护进程;如果我在main函数的sigset_t obj中添加一个信号,然后从main调用foo。然后,我在另一个sigset_t obj中向foo添加一个信号,比如sigprocmaskSIG_SETMASK、&foomask、&oldsmask。当我调用sigprocmaskSIG_SETMASK,&oldset,NULL时,sigprocmaskSIG_SETMASK,&oldset,NULL会做什么?我现在也在main中阻止SIGINT,但它仍然不工作。现在它正在清除。一个问题是,当sigprocmask中没有第三个参数,SIG_SETMASK如何,它是否会阻止信号掩码第二个参数中的信号。