分叉后中断信号的行为

分叉后中断信号的行为

我在研究信号时使用了以下代码。

#include<stdio.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>

int handler(int sig)
{
    printf("interrupt has been invoked\n");
}

int main(){
    pid_t pid;//pid_t is the datatype for process ids
    int status;

    signal(SIGINT,handler);
    if((pid=fork())==0)
    {
        while(1)
            sleep(1);
        exit(0);
    }
    else
    {
        wait(NULL);
    }
}

使用 ctrl+c 收到的输出是这样的:

^Cinterrupt has been invoked
interrupt has been invoked
^Cinterrupt has been invoked
interrupt has been invoked
^Cinterrupt has been invoked
interrupt has been invoked

有人可以解释为什么每次使用 ctrl+c 时都会打印两次“中断已被调用”吗?

答案1

这是因为在 fork() 调用之后,信号处理程序对父级和子级都有效。

由于分叉的子进程与父进程在同一进程组中运行,因此两个进程都会收到信号。

您可能喜欢使用这个 printf() 命令:

printf("interrupt has been invoked in pid %d\n", (int)getpid());

tty 驱动程序设置了一个 tty 进程组,如果您键入 ^C 并且 ^C 设置为 TTY INTR 字符,则 tty 驱动程序将 SIGINT 发送到与 tty 驱动程序位于同一进程组中的所有进程。

相关内容