C语言中的信号处理
我制作了以下程序来学习SIG_SETMASK的行为 下面的程序应该在func函数调用之前阻止SIGINT中断信号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函数生成的上一个信号列表,程
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如何,它是否会阻止信号掩码第二个参数中的信号。