【问题标题】:"Alarm Clock" interruption after first loop of the code第一次循环代码后的“闹钟”中断
【发布时间】:2020-10-06 19:03:45
【问题描述】:

这个无限程序创建了 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
 
 
}
}}
 
 
 
 
 
 
}

【问题讨论】:

  • This post 谈论wait(NULL) 的行为。
  • close(fd[0]) 紧接着是 read(fd[0])。也许你有一个错字。

标签: c linux terminal signals interruption


【解决方案1】:

考虑到 cmets 在第一个子进程中指出 close(fd[0]) 而不是 close(fd[1])。

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

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

您的代码中还有其他问题:

。 “ab”全局变量不在子进程之间共享。所以,当你在第一个孩子中修改它时,第二个孩子看不到修改。

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

【讨论】:

  • 非常感谢您的回答!我试着按照你说的保留记忆,它奏效了,在任何地方都找不到答案,所以谢谢。谈到全局变量,这实际上是一个更大的问题,哈哈,我正在尝试使用管道来使其工作。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多