使用pipe()和fork()从文件中读取并输出到console/new文件

Using pipe() and fork() to read from a file and output to the console/new file

本文关键字:文件 输出 console new 读取 fork 使用 pipe      更新时间:2023-10-16

我正在学习如何使用pipe()和fork()系统调用。我使用pipe和fork创建父进程和子进程,其中子进程将从文本文件中读取一个字符,然后通过管道将其发送给父进程,然后父进程将该字符输出到控制台,并将整个文本打印到控制台。稍后,我将对文件进行一些文本处理,让子进程读取和处理,然后将更新后的文本发送给父进程,但目前我只想确保pipe()的基础知识正确无误。

示例文件:

This is a test file; it is 1 of many.
Others will follow. 

相关代码:

pid = fork();
ifstream fin;
fin.open(inputFilename);
fin.get(inputChar);
if (pid == -1)
{
perror("Trouble");
exit(2);
}
else if (pid == 0) //child process that reads text file and writes to parent
{
close(pipefds[0]);
while(!fin.eof())
{
write(pipefds[1], &inputChar, sizeof(inputChar));
fin.get(inputChar);
}
close(pipefds[1]);
exit(0);
}
else
{
close(pipefds[1]);
read(pipefds[0], readbuffer, sizeof(readbuffer));
cout << readbuffer << endl;
close(pipefds[0]);
exit(0);
}
fin.close();

但是,当我编译和运行时,输出的长度总是不同的。有时它会打印整个文件,有时它只打印几个字母或半行。如.

This i

我试着浏览了手册页并进行了更多的研究,但一直找不到任何答案。我的程序到底发生了什么,它有时会从文件中读取所有内容,但其他时候不会。非常感谢您的帮助!

看起来好像您正试图通过一次对read(2)的调用从管道中读取所有数据。但是,与任何I/O操作一样,这可能总是返回比您请求的更少的字节。您应该始终检查read(2)write(2)系统调用(以及其他系统调用)的返回值,以确保它们按预期操作。

在这种情况下,您应该循环,直到您从子进程获得一些独立的通知,通知他们已经发送完数据。在这种情况下,这可以通过read(2)返回0来发出信号,这意味着子对象关闭了管道的末端。

您假设父级可以通过一个read()调用读取子级写入管道的所有内容。如果子级通过单个write()调用写入所有内容,只要总数据大小不超过管道内部缓冲区的大小,那么这对于管道来说可能是一个安全的假设。在这种情况下,当孩子通过许多小写入发送数据时,这根本不安全。

父级实际获得的数据量在一定程度上取决于其一个read()调用相对于子级写入的顺序。由于这两个过程是独立的,并且除了管道本身之外,您不使用任何IPC,因此基本上无法预测父级将成功读取多少数据。

在一般情况下,必须假设读取器需要执行多个read()调用来读取发送的所有数据。它必须继续调用read()并适当地处理结果数据,直到read的返回值指示发生I/O错误或到达文件末尾。请注意,文件结尾并不意味着现在没有更多的字节可用,而是意味着永远不会有更多的字节。这种情况发生在所有进程都关闭了管道写入端的所有副本之后。