C语言中kill系统调用的模糊行为

问题描述 投票:0回答:2

我制作了这个程序,到目前为止输出对我来说没有多大意义。有人可以解释一下发生了什么吗?

void handler1a(int x){
    printf("A\n");
}

int main(){
    signal(SIGUSR1, handler1a);
    int p = fork();
    if(p==0)
    {
        sleep(5);
        printf("L \n");
    }
    else
    {
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        //kill(0,SIGUSR1);
        wait(NULL);
    }
}

有3个终止信号,我的输出为-5A和1L。使用2个终止信号,输出为-4A和1L。使用4个终止信号,输出为6A和1L。好像最多2个杀死信号,父进程和子进程都在使用我的自定义处理程序但不知何故其中一个没有使用处理程序或者在收到信号两次之后没有得到kill信号(这将解释为什么只有当我在2次系统调用之后添加另一个kill系统调用时,会打印单个A.

c operating-system signals system-calls signal-handling
2个回答
4
投票

信号没有排队。因此,如果您多次向进程发送相同的信号,则可能会从1发送信号到发送信号的次数。

或者,换句话说,对于过程和信号的每个组合,信号可以处于信号状态。如果在该过程已经处于该信号的信号状态时向过程发送信号,则不会发生任何事情。

一个进程不能有两个SIGUSR1信号未决。 SIGUSR1正在等待或者不是。


1
投票

这里kill由父进程P调用,其中0作为其pid值,这意味着其组中的所有进程(P本身以及子C)将获得信号,并且将使用相同的自定义信号处理程序来处理它。

如果要向进程C发送多个相同类型的信号(这里是SIGUSR1),它们将不会排队,因为该信号将被阻塞,直到收到第一个信号,并且它们将被丢弃。

只有当C的信号处理程序返回时,C才准备好再次处理信号。这解释了为什么C调用处理程序的输出中的“A”更少。

您可以通过在处理程序中添加printf("A %d\n", getpid())来查看哪个进程调用了处理程序。

© www.soinside.com 2019 - 2024. All rights reserved.