我在Linux中有一个任务,但我无法使用它。
我有一个程序接收文本文件作为参数。然后,它使用fork()
创建子进程,并逐行将作为参数接收的文本文件的内容发送到子进程。子进程需要对行进行计数并返回父进程接收的行数。
这是我迄今为止所拥有的,但有些子进程没有收到所有的行。对于我的测试,我使用了一个包含9行的文本文件。父母将9行作为字符串发送,但子进程只收到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);
}
答案 0 :(得分:3)
您正在将null终止符发送到另一个进程:
write(p[1], string, (strlen(string)+1));
这会让结果变得混乱,因为当您打印收到的内容时,您只能看到空终结符。
如果你这样做:
write(p[1], string, strlen(string));
你应该得到你所期望的。
答案 1 :(得分:3)
管道是单向进程间通信通道。您必须创建2个管道,一个用于与子进程通信,另一个用于读取数据。
请记住在两个进程中关闭管道的未使用侧。
答案 2 :(得分:1)
您没有计算行数,而是计算read(2)
返回的次数。
使用管道时,read(2)
会从管道中提取尽可能多的数据:min(pipe_available, space_available)
。它不关心换行符,0
字节等。使它工作的简单技巧:
readbuffer
并寻找\n
fdopen
+ fgets
(我觉得这可能存在缺陷)答案 3 :(得分:1)
查看管道(man 2管道)的联机帮助页,您尝试编写的程序就是一个例子,与您的程序进行比较:)
答案 4 :(得分:0)
感谢您的建议。这就是我现在所拥有的,它的工作原理,但如何将答案发回给父母?因为父进程需要答案。
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);
}