使用C中的SIGUSR信号同步父和子。使父和子一个接一个地读

时间:2015-06-19 21:24:54

标签: c process

我使用两个管道在父进程和子进程之间创建了双向通信。父母和孩子写数据,我能够让他们互相读取数据。父写入数字1到5,并且子写入数字从6到10.但是我希望父项首先开始读取数据,然后按此顺序继续读取从父项切换到子项,直到读取所有数据:6,1, 7,2,8,3,9,4,10,5。我试图将读数与SIGUSR1同步,但是当父母第二次读取时程序停止。我已经搜索了很多,以找到问题所在,并尝试了一些技巧和类似的工作示例,但似乎没有任何帮助。这是我的代码:

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

void paction(int dummy)
{
   printf("P*************************************************\n");
} 

void caction(int dummy)
{
  printf("C*************************************************\n");
}

int main()
{
  int pfd[2];
  int pfd2[2];
  pid_t cfork, pfork;

    if (pipe(pfd) == -1 || pipe(pfd2) == -1) {
    fprintf(stderr,"Pipe failed");
    exit(1);
}

cfork = fork();

signal(SIGUSR1, paction);

 if (cfork == -1) {
     printf("Fork Failed\n");
     exit(1);
  }
 else if (cfork > 0) { /*parent process*/
 int numbers[] = {1, 2,3, 4, 5};
 int numbers2[] = {  6, 7,8, 9, 10 };

 close(pfd[0]);      /*close read end, write and then close write end*/
 /*write part*/

 int limit = 5;
 int i;
 for (i = 0; i < limit; i++) {
     printf("Parent sends: %d\n", numbers[i]);
     write(pfd[1], &numbers[i], sizeof(numbers[i]));

     printf("Child sends: %d\n", numbers2[i]);
     write(pfd2[1], &numbers2[i], sizeof(numbers2[i]));
   }
printf("***************************************************\n");

close(pfd[1]);
close(pfd2[1]);
/*read part/////////////////////////////////////////*/
    int temp;
    int reads = 5;
    int j;
    for (j = 0; j < reads; j++) {
    sleep(1);
        read(pfd2[0], &temp, sizeof(temp));
        printf("Parent gets: %d\n", temp);
    kill(cfork, SIGUSR1);
        pause();
    }
 /*printf("***************************************************\n");*/
  kill( cfork, SIGUSR1 );
  close(pfd2[0]);       
}
else { /*child process*/

  signal(SIGUSR1, caction);
  close(pfd[1]);
  int temp;
  int reads = 5;
  int j;
  pfork = getppid();
    for (j = 0; j < reads; j++) {    
      sleep(1);
      read(pfd[0], &temp, sizeof(temp));
      printf("Child gets: %d\n", temp);
      kill(getppid(), SIGUSR1);
      pause();
    }
/*printf("***************************************************\n");*/
  close(pfd[0]);
  close(pfd2[0]);

}

return 0;

}

我的输出如下:

> Parent sends:1 
> Child sends:6 
> Parent sends:2 
> Child sends:7 
> Parent sends:3 
> Child sends:8 
> Parent sends:4 
> Child sends:9 
> Parent sends:5
> Child sends:10
> ************************************************************** 
  Parent gets:6
> C************************************************************
> Child gets:1
> P************************************************************* 
> Parent gets:7

这就是它停止的时候。 如果有人可以帮助我,我会非常感激,因为我真的想知道问题出在哪里,因为我是C编程和流程的初学者! 提前谢谢

2 个答案:

答案 0 :(得分:0)

printf()不是异步安全函数。在普通代码和信号处理程序中调用printf()将导致未定义的行为。特别是,printf()可能需要对输出流进行锁定,而在信号处理程序中获取锁定非常是不可取的(自我死锁的风险)。

答案 1 :(得分:0)

使用信号也许是一个坏主意,但我有一个任务,分配它来使用SIGUSR1。我通过添加:

解决了这个问题
static struct sigaction pact, cact;  
/* set SIGUSR1 action for parent */;
pact.sa_handler = p_action;
sigaction(SIGUSR1, &pact, NULL);

在为父母分配了第一个动作之后,它运行良好。

谢谢:)