我在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); }