C

时间:2019-02-14 09:43:41

标签: c operating-system signals system-calls signal-handling

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

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信号,父进程和子进程都在使用我的自定义处理程序,但是不知何故其中之一没有使用该处理程序,或者在已经两次收到该信号之后未获得kill信号(这将解释为什么仅当我在2个终止系统调用之后添加另一个终止系统调用时,将打印一个A。

2 个答案:

答案 0 :(得分:4)

信号没有排队。因此,如果您多次向一个进程发送同一信号,则它可能会被处理从1到您发送信号的次数之间的任意次数。

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

一个进程不能有两个SIGUSR1信号挂起。 SIGUSR1处于挂起状态或没有挂起。

答案 1 :(得分:1)

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

如果您要向进程 C 发送相同类型(此处为SIGUSR1)的多个信号,则不会将它们排队,因为在接收到第一个信号之前,该信号将被阻塞被处理,它们将被丢弃。

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

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