使用pipe道发送多个string到subprocess

我在Linux有一个任务,我不能得到它的工作。

我有一个程序接收一个文本文件作为参数。 然后使用fork()创build一个subprocess,并将接收到的文本文件的内容作为参数逐行发送给subprocess。 subprocess需要对行进行计数,并返回父进程收到的行数。

这是我到现在为止,但有点儿童进程并没有收到所有的线。 对于我的testing,我用了9行的文本文件。 父母发送9行作为string,但subprocess只收到2或3个。

我究竟做错了什么?

 #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char string[80]; char readbuffer[80]; int pid, p[2]; FILE *fp; int i=0; if(argc != 2) { printf("Syntax: %s [file_name]\n", argv[0]); return 0; } fp = fopen(argv[1], "r"); if(!fp) { printf("Error: File '%s' does not exist.\n", argv[1]); return 0; } if(pipe(p) == -1) { printf("Error: Creating pipe failed.\n"); exit(0); } // creates the child process if((pid=fork()) == -1) { printf("Error: Child process could not be created.\n"); exit(0); } /* Main process */ if (pid) { // close the read close(p[0]); while(fgets(string,sizeof(string),fp) != NULL) { write(p[1], string, (strlen(string)+1)); printf("%s\n",string); } // close the write close(p[1]); wait(0); } // child process else { // close the write close(p[1]); while(read(p[0],readbuffer, sizeof(readbuffer)) != 0) { printf("Received string: %s\n", readbuffer); } // close the read close(p[0]); } fclose(fp); } 

管道是单向进程间通信信道。 您必须创建2个管道,一个用于向子进程发言,另一个用于读取数据。

请记住在两个进程中关闭管道未使用的一面。

您正在将空终止符发送到另一个进程:

  write(p[1], string, (strlen(string)+1)); 

这使得结果混乱,因为当你打印你收到的东西时,你只能看到空终止符。

如果你这样做:

  write(p[1], string, strlen(string)); 

你应该得到你所期望的。

你不计算行数,你正在计算read(2)返回的次数。

使用管道时, read(2)将从管道中获取尽可能多的数据: min(pipe_available, space_available) 。 它不关心换行符, 0字节等简单的技巧,使其工作:

  • 使用循环来readbuffer并查找\n
  • 使用fdopen + fgets (我有一种感觉可能是有缺陷的)

看看管道的manpage(man 2管道),你正在编写的程序就是一个例子,与你的比较:)

谢谢你的建议。 这是我现在和它的工作,但如何将答案发回给家长? 因为父进程需要答案。

 if (pid) /* Main process */ { /* Close the read */ close(p[0]); while(fgets(string,sizeof(string),fp) != NULL) { write(p[1], string, (strlen(string))); } /* Close the write */ close(p[1]); wait(0); printf("\nMain process with PID=%d has terminated succesfully.\n", getpid()); } else /* Child process */ { /* Close the write */ close(p[1]); while( read(p[0], readbuffer, sizeof(readbuffer)) > 0) { int j=0; for(j; j<sizeof(readbuffer); j++) { if (readbuffer[j] == '\n') { i++; } } } /* Close the read */ close(p[0]); printf("\nChild process with PID=%d has terminated succesfully.\nChild process received %d lines from the parent process.\n",getpid(), i); }