简体   繁体   中英

Q: Read line to line from file and send to child process with pipes

What I want to do is reading every different line from a .txt and send each line to one of the child processes, and each one will print its own line. Something like this: Txt:Abc def rev

Child process 1 will read Abc, child process 2 will read def and so on.

// Includes

// the child just get the file descriptor to read (the pipe)
void child(int fd) {
  char buf[100];  // buffer to store data read
  int ret;        // the number of bytes that are read

  while((ret = read(fd, buf, sizeof(buf))) > 0) {
    // write the 'ret' bytes to STDOUT (which as file descriptor 1)
    write(1, buf, ret);
  }
}

int main (void) {
  pid_t pid;
  char buf[100];
  int N_CHILDREN = 2;
  int p[N_CHILDREN][2];
  int i,j, ret;
  int fdi;
  // create the pipes
  for(i=0; i<N_CHILDREN; i++) {
    if (pipe(p[i]) == -1) {
      perror("pipe");  // ALWAYS check for errors
      exit(1);
    }
  }
  //open the file       
  fdi = open("123.txt",O_RDONLY);
  if (fdi < 0) {
    perror("open"); // ALWAYS check for errors
    exit(1);
  }
  // just spawn the children
  for(j=0; j < N_CHILDREN;j++) { 
    pid = fork();
    if (pid < 0) {
      perror("fork"); // ALWAYS check for errors
      exit(1);
    }
    if (pid == 0) {  // child
      close(p[j][1]);  // close the writing part
      child(p[j][0]);  // call child function with corresp. FD
      exit(0);  // leave : the child should do nothing else
    }
  }
  // don't need that part
  for(j=0; j<N_CHILDREN; j++) {
    close(p[j][0]);  // close the read-part of pipes
  }
  // need to read file content, see comment in child() function
  while ((ret = read(fdi, buf, sizeof(buf))) > 0) {
    // write the data to all children
    for(j=0; j<N_CHILDREN; j++) {
      write(p[j][1], buf , ret); // we write the size we get
    }
  }
  // close everithing
  for(j=0; j<N_CHILDREN; j++) {
    close(p[j][1]);  // needed, see text after
  }
  close(fdi); // close read file
  return(0); // main returns a int, 0 is "ok"
}

This is the code I've got, as you can see it gets the whole content of the file and prints it as many times as childs there are.

Reading lines is hard with the low-level system calls, unless you read one character at a time. Instead you could use the standard CI/O functions like fgets to read a line into the buffer and send it over the pipe to the child processes.

As for how to send separate lines to the separate processes, skip the inner loop and instead keep the current child process index in a variable, which you increase at the end of the loop and use the modulo operator to "reset" it to zero when it's about to overflow.

Something like

int current_child = 0;  // Start with the first child
while (fgets(buf, sizeof buf, fp) != NULL)
{
    // Send to current_child

    // Continue to next child process
    // Reset to zero if going of the end of the child-list
    current_child = (current_child + 1) % N_CHILDREN;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM