问:从文件中逐行读取并使用管道发送到 child 进程

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

我想要做的是从 .txt 中读取每一行,并将每一行发送到 child 进程之一,每个进程都会打印自己的行。 是这样的: Txt:Abc 定义 转

Child 进程 1 将读取 Abc,child 进程 2 将读取 def 等等。

// 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"
}

这是我得到的代码,如您所见,它获取文件的全部内容并打印 child 次。

使用低级系统调用很难读取行,除非您一次读取一个字符。相反,您可以使用标准的 C I/O 函数,如 fgets 将一行读入缓冲区并通过管道将其发送到子进程。

至于如何将单独的行发送到单独的进程,跳过内部循环,而是将当前子进程索引保存在一个变量中,您在循环结束时增加该变量并使用模运算符 "reset"快溢出的时候归零

类似

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;
}