嗯,父进程直到第一个子进程结束后才发送任何信号(因此它没有机会代表它)。它只创建一个子进程,在数组中注册其pid
pidt[0]
(此数组位于与其子级共享的内存段中)并为
SIGUSR1
信号(没有用,因为
exit()
就在那之后(它几乎没有时间接收信号,但读得更多,就不行了)。然后,家长
wait()
第一个孩子的死
(这是错误的)。。。发生了什么。。。所以之后只有一个过程。
然后,父进程安装一个信号处理程序并创建第二个子进程。它是
kill()
由子进程执行,您可以从信号处理程序执行后的输出中看到这一点。由于没有第一个孩子还活着,因此没有机会接收到信号,也没有机会看到预期的输出(您不会说预期会有此输出,但我猜:))
$ a.out
pid du processus père 3095
1 processus fils 3097
pid enregistré= 3097
pid du processus père 3095
2 processus fils 3098-> envoie SIGUSR1 au père 3095
pid du processus père 3095
SIG HANDLER received SIGUSR1 by process 3095
-> Envoie du signal SIGUSR1 au fils 3097
------ Fin du programme -------$ _
(看,没有
\n
在最后一条消息的末尾,因此您会立即收到提示)
注意事项
最后杀死孩子的父母可以
等待()
父级正在使用的系统调用,用于等待第二个子级被中断(您不检查它的返回值),因此,最终
printf()
可以在第二个子级实际退出之前执行(子级除了
退出()
因此,在孩子最终退出后,什么都看不到,但你也必须检查这一点)。
关于父信号处理程序中发送的信号。。。。三思:您已经启动了第二个子系统(即向父系统发送第一个信号的子系统)
在第一个孩子
exit(2)
预计起飞时间
,因此它不可能接收到信号。您没有检查
kill(2)
syscall,因为它会告诉您目标进程不存在。
以下代码修复损坏的零件。。。首先,父母不能等待孩子死亡。在安装其信号处理程序后,子级必须处于活动状态并等待信号(这就是
pause(2)
是否,等待信号到达):
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/wait.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <time.h>
# include <signal.h>
# include <sys/mman.h>
static pid_t* pidt;
// handler signal père
void sig_handler(int signo)
{
if (signo == SIGUSR1) {
printf("SIG HANDLER received SIGUSR1 by process %d\n", getpid());
printf("-> Envoie du signal SIGUSR1 au fils %d\n", pidt[0]);
// le père envoie un signal au premier fils
kill(pidt[0], SIGUSR1);
}
}
// handler signal fils
void sig_handlerr(int signo)
{
if (signo == SIGUSR1) {
printf("SIG HANDLER2 received SIGUSR1 by process %d\n", getpid());
}
}
int main(int argc, char* argv[]) {
printf("pid du processus père %d\n", getpid());
pidt = mmap(NULL, sizeof(pid_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (fork()==0) {
printf("1 processus fils %d\n", getpid());
pidt[0]=getpid();
printf("pid enregistré= %d\n", pidt[0]);
signal(SIGUSR1, sig_handlerr);
pause();
exit(0);
}
signal(SIGUSR1, sig_handler);
if (fork()==0) {
printf("2 processus fils %d", getpid());
// il envoie un signal SIGUSR1 au processsu père
printf("-> envoie SIGUSR1 au père %d\n", getppid());
kill(getppid(), SIGUSR1); // envoie un signal SIGUSR1 au processus père
exit(0);
}
wait(NULL);
printf("\n\n------ Fin du programme -------");
return EXIT_SUCCESS;
}
您将获得以下输出:
$ a.out
pid du processus père 3301
2 processus fils 3304-> envoie SIGUSR1 au père 3301
pid du processus père 3301
1 processus fils 3303
pid enregistré= 3303
SIG HANDLER2 received SIGUSR1 by process 3303
pid du processus père 3301
SIG HANDLER received SIGUSR1 by process 3301
-> Envoie du signal SIGUSR1 au fils 3303
------ Fin du programme -------$ _
(同样,在最后一条消息之后出现提示:))
您的代码与我的代码之间的差异如下,请注意这些差异:
$ diff -c a-old.c a-new.c
*** a-old.c 2017-12-18 11:54:51.000000000 +0100
--- a-new.c 2017-12-18 11:43:21.000000000 +0100
***************
*** 42,50 ****
pidt[0]=getpid();
printf("pid enregistré= %d\n", pidt[0]);
signal(SIGUSR1, sig_handlerr);
exit(0);
}
- wait(NULL);
signal(SIGUSR1, sig_handler);
--- 42,50 ----
pidt[0]=getpid();
printf("pid enregistré= %d\n", pidt[0]);
signal(SIGUSR1, sig_handlerr);
+ pause(); /* wait for a signal to arrive */
exit(0);
}
signal(SIGUSR1, sig_handler);