我想让父进程和子进程读取一个. txt文件的内容,一个字节一个字节地读取。父进程将一个字节一个字节地写入b. txt文件。子进程将一个字节一个字节地写入c. txt文件。
父级和子级正在阅读同一文件并写入同一文件
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main(argc,argv)
int argc;
char *argv[];
{
int fdrt,fdwt2,fdwt3;
char c;
char parent='P';
char child='C';
int pid;
unisigned long i;
if(argc !=4) exit(1);
if((fdrd =open(argv[1],O_RDONLY))==-1)
exit(1);
if((fdwt2=creat(argv[2],0666))==-1)
exit(1);
if((fdwt3=creat(argv[3],0666))==-1)
exit(1);
printf("Parent:creating a child process\n");
pid=fork();
if(pid==0){
printf("Child process starts,id= %d\n",getpid());
for(;;)
{
if(read(fdrd,&c,1)!=1) break;
if(i=0;i<50000;i++);
write(1,&child,1);
write(fdwt2,&c,1);
}
exit(0);
}
else
{
printf("Parent starts,id= %d\n",getpid());
for(;;)
{
if(read(fdrd,&c,1)!=1) break;
if(i=0;i<50000;i++);
write(1,&parent,1);
write(fdwt3,&c,1);
}
wait(0);
}
}
2条答案
按热度按时间eaf3rand1#
当你
open
或creat
一个文件时,系统会创建一个内核“文件对象”来跟踪打开的文件(跟踪你在文件中阅读/写的位置等),并返回一个引用它的“文件描述符”。这个文件描述符只是一个句柄,你可以有多个文件描述符引用同一个文件对象。当你
fork
一个子文件时,子文件会得到所有父文件描述符的副本,但是文件对象并没有被复制--子文件中的文件描述符引用同一个文件对象。所以当你open
一个读取的文件,然后fork
,父文件和子文件共享一个文件对象,这意味着当任何一个读取文件时,它将文件中的读取位置前移,因此当另一个从文件中读取时,它将从前移点而不是开始处获取字节。实际效果是源文件中的字节将在父进程和子进程之间被“分割”--每个进程将获得一些字节,但不是全部。哪些字节将被分配到哪个进程取决于时间,很难预测。
为了避免这种情况,您需要
open
源文件 after 调用fork。这将导致打开文件两次(一次在父文件中,一次在子文件中),从而创建两个文件对象来跟踪读取位置,并允许父文件和子文件独立读取文件。v1l68za42#
即使你找到了一种同时阅读同一个文件的方法,这可能是不明智的,可能会导致数据损坏。如果你真的需要两个进程,并且真的需要从两个进程读写一个. txt文件,你可以通过打开读/写,并在每次读写数据时关闭文件来做到这一点。这是安全的,但性能不会很好。
如果你只从父节点和子节点阅读,你可以在fork之后打开,这样就可以打开读取两次。
通过在fork()之后打开这些文件,您可以只从父文件写入b.txt,只从子文件写入c.txt,而不会出现任何问题。
要在父进程和子进程之间有效地进行通信,可以使用管道,但在管道中可以发送的数据量不如在文件中发送的数据量大。在管道可以实现此目的的情况下使用文件可能是不好的做法。