简体   繁体   English

子进程在重定向的标准输出上打印,父进程从未收到

[英]Child process prints on redirected stdout, parent never receives

I'm a beginner when it comes to C and I'm writing this program where I have an array at the beginning and have to fork twice so that I have two child processes. 我是C语言的初学者,我正在写此程序,其中我的开头有一个数组,必须进行两次分叉,以便有两个子进程。 Each child process gets half of the parent's array and executes the program based on it, making it recursive. 每个子进程都获取父级数组的一半,并基于该数组执行程序,从而使其递归。

When a child gets an array containing only one element, that element is printed on stdout and then it exits. 当孩子得到一个仅包含一个元素的数组时,该元素将被打印在stdout上,然后退出。

Each parent then reads what its two children send on stdout and makes a calculation based on it. 然后,每个父级读取其两个子级在stdout上发送的内容,并根据该值进行计算。 The result of the calculation is an array that is then being printed also on the stdout for the parent's parent's calculation. 计算的结果是一个数组,然后该数组也被打印在标准输出上,用于父级的父级计算。

What's not working: I'm getting to the end of the recursion and printing out the value of the 1-element array in each child, but the parent can't seem to read it. 什么不起作用:我要递归结束,并在每个孩子中打印出1-element数组的值,但是父母似乎无法读取它。 It never enters the while loop where I'm using fgets(). 它永远不会进入使用fgets()的while循环。

This is the part in parent where I'm splitting the array in two. 这是父级中将数组分成两部分的部分。 Here I'm also giving out the value (without doing anything else) in case I get an array with one value: 在这里,我还给出了值(不做任何其他事情),以防我得到带有一个值的数组:

while( fgets(strBuffer, sizeof(strBuffer), stdin)!= NULL){

  if(counter % 2 == 0){

    if(evenCounter == evenMax){
      evenMax++;
      evenBuffer = (char**) realloc(evenBuffer, evenMax * 
      sizeof(char*));

   }if(evenBuffer == NULL){
     fprintf(stderr, "error reallocating evenBuffer\n");
     exit(1);
   }

    evenBuffer[evenCounter] = (char*) malloc(100*sizeof(char));
    strcpy(evenBuffer[evenCounter], strBuffer);
    evenCounter += 1;

  } else {

    if(oddCounter == oddMax){
      oddMax ++;
      oddBuffer = (char**) realloc(oddBuffer, oddMax * 
            sizeof(char*));
    }if(oddBuffer == NULL){
      fprintf(stderr, "error reallocating oddBuffer\n");
      exit(1);
    }

    oddBuffer[oddCounter] = (char*) malloc(100*sizeof(char));
    strcpy(oddBuffer[oddCounter], strBuffer);
    ddCounter += 1;
  }

  counter ++;

}

if(counter == 1){
  fprintf(stdout, "%s\n", evenBuffer[0]);
  //  fprintf(stderr, "LAAAAST %s\n", evenBuffer[0]);
  fflush(stdout);
  exit(0);
}


if(oddCounter != evenCounter){
  fprintf(stderr, "evenCounter size:%d, oddCounter:%d\n", 
  evenCounter, oddCounter);
  exit(EXIT_FAILURE);
}

Here's the code part where the children are created and the pipes are created and redirected. 这是创建子代以及创建和重定向管道的代码部分。

  int k1pipe_from[2];
  int k1pipe_to[2];
  pipe(k1pipe_from);
  pipe(k1pipe_to);

  int k2pipe_from[2];
  int k2pipe_to[2];
  pipe(k2pipe_from);
  pipe(k2pipe_to);

  pid_t pid = fork();
  pid_t pid2;

 switch(pid){
  case -1:
    fprintf(stderr, "Cannot fork!\n");
    exit(EXIT_FAILURE);
  case 0://child 1
    fprintf(stderr, "Child 1 created, pid: %d\n", getpid());

    close(k2pipe_from[1]);
    close(k2pipe_to[0]);

    close(k1pipe_from[1]);
    close(k1pipe_to[0]);

    dup2(k1pipe_from[0], STDIN_FILENO);
    close(k1pipe_from[0]);
    dup2(k1pipe_to[1], STDOUT_FILENO);
    close(k1pipe_to[1]);

    fflush(stdout);
    execl("forkFFT", "forkFFT", NULL);
    break;
 default:
   close(k1pipe_to[1]);
   close(k1pipe_from[0]);
   fflush(stdout);
}

pid2 = fork();
switch(pid2){
  case -1:
   fprintf(stderr, "Cannot fork!\n");
   exit(EXIT_FAILURE);
  case 0://child 2
   close(k1pipe_from[1]);
   close(k1pipe_to[0]);
   close(k2pipe_from[1]);
   close(k2pipe_to[0]);

   dup2(k2pipe_from[0], STDIN_FILENO);
   close(k2pipe_from[0]);
   dup2(k2pipe_to[1], STDOUT_FILENO);
   close(k2pipe_to[1]);
   fflush(stdout);

   execl("forkFFT", "forkFFT", NULL);
   break;
  default:
   close(k2pipe_to[1]);
   close(k2pipe_from[0]);
}

Here's the part where I'm reading what one of the child processes has written on its redirected stdout. 这是我正在阅读其中一个子进程在其重定向的stdout上编写的内容的部分。

FILE* k1File = fdopen(k1pipe_to[0], "r+");
char r1Buffer[1000];
evenResCounter = 0;
char* pend1;

while(fgets(r1Buffer, strlen(r1Buffer), k1File) != NULL){
  double real = (double) strtof(r1Buffer, &pend1);
  double img = 0.00;
  if(pend1 != NULL){
    img = (double) strtof(pend1, NULL);
  }

  evenRes[evenResCounter] = real + img * I;

  evenResCounter ++;

}

close(k1pipe_to[0]);

Here's the part with the calculation, after which the parent prints out the calculated array: 这是计算的一部分,之后父级将打印出计算出的数组:

double pi = 3.141592654;
int total_elem = evenResCounter + oddResCounter;
double complex transArray[total_elem];
int k = 0;
int half = total_elem/2;

while(k <= half){
  transArray[k] = evenRes[k] + (cos(-2*pi/total_elem*k) + I * sin(-2*pi/total_elem*k)) * oddRes[k];
  transArray[k + half] = evenRes[k] - (cos(-2*pi/total_elem*k) + I * sin(-2*pi/total_elem*k)) * oddRes[k];
  k++;
}

int final_counter = 0;
while(final_counter != total_elem){
  fprintf(stdout, "%f %f*i\n", creal(transArray[final_counter]), cimag(transArray[final_counter]));
}

Would be super grateful for any help. 非常感谢您的帮助。

  1. You should get pipe for child send message to parent 您应该获得给孩子发送消息的pipe
  2. In child, redirect stdout to pipe , recursive or just output data 在子级中,将stdout重定向到pipe ,递归或仅输出数据
  3. In parent, redirect stdin to pipe , get data, if in main process , call calculation() , else just call output_data() 在父母,重定向stdinpipe ,获取数据,如果在main process ,调用calculation()否则只需调用output_data()

The following code just get the sum of each data, you could change it in calculation() : 以下代码仅获取每个数据的总和,您可以在calculation()更改:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int sum = 0;

void output_data(int data) {
  printf("%d\n", data);
}

void calculation(int data) {
  sum += data;
}

void child(int* array, int left, int right, bool in_main_process) {
  if (left == right)
    exit(0);
  if (left + 1 == right) {
    in_main_process ? calculation(array[left]) : output_data(array[left]);
    exit(0);
  }

  int mid = (left + right) / 2;

  int pipe_fd_1[2];
  pipe(pipe_fd_1);

  if (fork() == 0) { // child 1
    close(pipe_fd_1[0]);
    dup2(pipe_fd_1[1], STDOUT_FILENO);
    close(pipe_fd_1[1]);
    child(array, left, mid, false);
    exit(1);
  }

  int pipe_fd_2[2];
  pipe(pipe_fd_2);
  if (fork() == 0) { // child 2
    close(pipe_fd_2[0]);
    dup2(pipe_fd_2[1], STDOUT_FILENO);
    close(pipe_fd_2[1]);
    child(array, mid, right, false);
    exit(1);
  }

  close(pipe_fd_1[1]);
  dup2(pipe_fd_1[0], STDIN_FILENO);
  close(pipe_fd_1[0]);

  int data;
  while (scanf("%d", &data) == 1)
    in_main_process ? calculation(data) : output_data(data);

  close(pipe_fd_2[1]);
  dup2(pipe_fd_2[0], STDIN_FILENO);
  close(pipe_fd_2[0]);

  while (scanf("%d", &data) == 1)
    in_main_process ? calculation(data) : output_data(data);
}

int main() {
  int array[6] = {1, 2, 3, 4, 5, 6};

  int left  = 0;
  int right = sizeof(array) / sizeof(array[0]);
  child(array, left, right, true);
  printf("%d\n", sum);

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 分叉的孩子“打印”两次重定向标准输出 - Forked child “prints” redirected stdout twice 子进程接收父进程的 SIGINT - Child process receives parent's SIGINT 子进程(通过CreateProcess)通过重定向的stdout和stdin停滞在getch()上 - Child process (via CreateProcess) stalls on getch() with redirected stdout and stdin 如何丢弃子进程的标准输出但保留父进程的标准输出? - How to discard stdout of child process but keep stdout of parent process? 您可以选择哪个子进程接收来自父进程的消息吗? - Can you choose which child process receives a message from a parent? 在OSX上创建子进程并将子进程的stdin和stdout重定向到父进程? - Create child process on OSX and redirect stdin and stdout of child process to parent process? 无法通过DLL注入正确重定向进程的标准输出 - Stdout of process not redirected properly via dll injection 让子进程 printf 正确重定向标准输出 - Having child processes printf to redirected stdout correctly linux永远不会终止子进程,直到父进程结束? - does linux never end child process until the parent ends? 子进程如何从管道读取stdout,而父进程如何将stdin写入管道? - How can the child process read stdout from the pipe and the parent process write stdin to the pipe?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM