我已经制作了这个程序,到目前为止的输出对我来说意义不大。有人可以解释发生了什么吗?
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。
答案 0 :(得分:4)
信号没有排队。因此,如果您多次向一个进程发送同一信号,则它可能会被处理从1到您发送信号的次数之间的任意次数。
或者,换句话说,对于过程和信号的每种组合,信号可以处于信号状态。如果您在某个进程已经处于该信号的信号状态时向该进程发送信号,则不会发生任何事情。
一个进程不能有两个SIGUSR1信号挂起。 SIGUSR1处于挂起状态或没有挂起。
答案 1 :(得分:1)
此处kill
由父进程 P 调用,以0
作为其pid值,这意味着其组中的所有进程( P 本身以及子级 C )将获取信号,并将使用相同的自定义信号处理程序来处理该信号。
如果您要向进程 C 发送相同类型(此处为SIGUSR1
)的多个信号,则不会将它们排队,因为在接收到第一个信号之前,该信号将被阻塞被处理,它们将被丢弃。
仅当 C 的信号处理程序返回时, C 即可准备再次处理信号。这解释了为什么 C 调用处理程序时输出中的“ A”更少。
通过在处理程序内部添加printf("A %d\n", getpid())
,可以查看哪个进程调用了该处理程序。