"Alarm Clock" 代码第一次循环后中断

"Alarm Clock" interruption after first loop of the code

这个无限程序创建了 2 个子进程,并在 while() 循环中设置了一个持续 3 秒的 alarm(),然后向两个子进程发送信号,以便它们打印出一些东西。当我执行时,代码的第一个循环工作并且其中一个子进程打印了一些东西,但后来我在终端中收到“闹钟”中断,为什么会这样? (最后检查while循环,我猜问题就在那里)。

#include <stdio.h>
#include <unistd.h>
#include<stdlib.h>
#include <sys/types.h>
#include <stdbool.h>
#include <sys/wait.h>
#include<string.h>
#include<signal.h>

void passage(int);
void AB(int);
void BA(int);

 bool ab =false;

 int pid[2];
 int i =1;
 
 void passage(int signum) //handler
 {
 printf("Voiture %d passée\n", i); i++; ab = !ab;
  
  
 }

 
 void AB(int sig)
 {
 
  if(ab == false)
  {
   printf("feu1: ROUGE | feu2: VERT\n");  ab = !ab;
  }
 
  
 }
 
 
 void BA(int sig)
 {
 
  if(ab == true)
  {
   printf("feu1: VERT | feu2: ROUGE\n");
  }
 
 }

 int main() 
{ 
 
 struct sigaction action;
 action.sa_handler = passage;
 sigaction(SIGALRM,&action,NULL);
 
 
 int fd[2];
 if(pipe(fd)==-1) { printf("pipe error"); return 1;}
 
 
 pid[0]=fork();
 if(pid[0] != -1 )
 {
 if (pid[0]==0)
{
 close(fd[0]);
  bool y;
  read(fd[0], &y, sizeof(_Bool));
  close(fd[0]);
 // Code du child 1
  printf("test1\n");
 
 signal(SIGUSR1,AB);
 while(1);

 
} else
{
 
 
 pid[1]=fork();
 if(pid[1]==0)
 {
 // Code child 2  
 printf("test2\n");
 signal(SIGUSR2,BA);
 while(1);
 

}else
{
 // parent precessus
 //send signals to the two childs after 3s
 printf("PONT OUVERT\n");
  close(fd[0]);
  write(fd[1], &ab, sizeof(_Bool));
  close(fd[1]);
 while(1)
 { 
  
 
  alarm(3);
  pause();
  kill(pid[0],SIGUSR1);
  kill(pid[1],SIGUSR2);
  
 

 }
 while( wait(NULL) != -1);                                             //    gcc test.c -o test
 
 
}
}}
 
 
 
 
 
 
}

考虑在第一个 child 过程中指出 close(fd[0]) 而不是 close(fd[1]) 的注释。

但主要问题是您没有正确初始化“sigaction”结构。您必须重置它,否则您在字段中有垃圾值:

   struct sigaction action;
   memset(&action, 0, sizeof(action));
   action.sa_handler = passage;
   sigaction(SIGALRM,&action,NULL);

您的代码还有其他问题:

。 child 进程之间不共享“ab”全局变量。所以,当你在第一个child修改的时候,第二个child是看不到修改的。

。 “同时(1);”循环消耗太多 CPU。您应该添加一个暂停:while(1) pause();