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

C语言中kill系统调用的模糊行为,c,operating-system,signals,system-calls,signal-handling,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,S

我已经做了这个程序,到目前为止输出对我来说没有多大意义。有人能解释一下发生了什么事吗

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次kill系统调用后添加另一个kill系统调用时只打印一个a).

信号不排队。因此,如果多次向进程发送同一信号,它可能会被处理任意次数,从1到发送信号的次数不等

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


一个进程不能有两个挂起的SIGUSR1信号。SIGUSR1挂起或未挂起。

信号未排队。因此,如果多次向进程发送同一信号,它可能会被处理任意次数,从1到发送信号的次数不等

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


一个进程不能有两个挂起的SIGUSR1信号。SIGUSR1是挂起的还是未挂起的。

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

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

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


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

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

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

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


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

您不能在信号处理程序中安全地调用
printf()
。Per:“因此,信号处理程序通常不能从信号处理程序中调用标准库函数。”不是async-signale-safe。最好使用
sigaction
而不是
signal
。信号发生时,信号处理程序可能会重置。POSIX.1允许这种依赖于实现的行为。您不能在信号处理程序中安全地调用
printf()
。根据:“因此,信号处理程序通常不能调用标准库函数。”在信号处理程序中,但
printf()
不是异步信号安全的。最好使用
sigaction
而不是
signal
。信号发生时,信号处理程序可能会重置。POSIX.1允许这种依赖于实现的行为。