Unix C编程:多个管道和叉子

时间:2015-11-06 21:14:02

标签: c linux unix

我正在尝试根据可用CPU的数量来解决分配问题。然后我需要相应地创建子进程的数量和双向管道以在父进程与每个子进程之间进行通信。例如,有4个可用的CPU,我需要创建3个子项(fork()3次),并创建6个管道。我搜索了不同的来源,他们通常创建例如// int pipefd [2]然后管道(pipefd);我的第一个想法是在找到CPU的数量之后,我按以下代码构建矩阵:

  /* Find # of CPU and minus 1 */
  cpu_num = (sysconf (_SC_NPROCESSORS_ONLN)) - 1;

  /* Pipe creation */
  /* 2 Pipes for 1 child */
  enum {p_read, p_write};
  for (i = 0; i < (cpu_num); i++) {
    int ptcfd[i][2];
    if (pipe(ptcfd[i]) < 0) {
      perror("Parent to Child Pipe Error");
      exit(20);
    }
    int ptpfd[i][2];
    if (pipe(ptpfd[i]) < 0) {
      perror("Child to Parent Pipe Error");
       exit(20);
    }
  }

  char buf[PIPE_BUFF_LEN]; /* create Buffer with size 1024 */

  /* Array to store children PID */
  int childid[cpu_num];

  /* Children preparation task */
  for (i = 0; i < cpu_num; i++) {
    pid = fork();
    /* Failed to fork section */
    /* Creating error message */
    if (pid < 0) {
      printf("Failed to create fork PID #%d. \n\n", getpid());
      exit(44);
    }

    /* Parent */
    /* Record PID into childid array for later use */
    if (pid > 0) {
        close(ptpfd[i][p_write]);
        close(ptcfd[i][p_read]);
        childid[i] = pid;
    }
    /* Child */
    if (pid == 0) {
        close(ptcfd[i][p_write]);
        close(ptpfd[i][p_read]);
    }
  }

假设我有4个CPU。 但是当我尝试编译时,这些似乎并不正确,它说: main.c:138:12:错误:'ptpfd'未声明(在此函数中首次使用)close(ptpfd [i] [p_write]);

main.c:138:12:注意:每个未声明的标识符仅针对它出现的每个函数报告一次

main.c:139:12:错误:'ptcfd'未声明(首次使用此功能) 关闭(ptcfd [I] [p_read]);

所以我开始思考(但无法通过谷歌搜索确认)可能我不需要使用矩阵来创建6个管道,我只需要创建常规的2路管道:ptpfd [2]和ptcfd [2 ],然后在我fork()之后,每个孩子只会继承自己的2个管道?如果我的假设是错误的,请帮助我,谢谢

1 个答案:

答案 0 :(得分:1)

C实现变量的块范围。您在第一个调用ptpfd的{​​{1}}循环中声明了ptcfdfor数组,然后尝试在第二个pipe()循环中使用它们致电for。你应该在循环之外声明数组,这样它们在整个函数中都是可见的。

此外,阵列的大小是错误的。你声明了fork()。所以在循环的第一次迭代中,它将是一个0x2数组,在第二次迭代时它将是一个1x2数组,在第三次迭代时它将是2x2,依此类推。数组的大小应该基于你要分支的进程数,即int ptpfd[i][2],所以应该声明:

cpu_num
然后

int ptpfd[cpu_num][2]; int ptcfd[cpu_num][2]; 将成为每个子进程的管道的这些数组的索引。