I want to parent and child process read the contents of a.txt file, byte by byte. And parent process write byte by byte to the b.txt file. child process write byte by byte to the c.txt file.
Parent and child are working on reading from the same file and writing to the same file
#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);
}
}
CodePudding user response:
When you open
or creat
a file, the system creates a kernel "file object" that tracks the open file (tracking where in the file you are reading/writing, among other things) and returns a "file descriptor" that refers to it. That file descriptor is just a handle, and you can have mulitple file descriptors that refer to the same file object.
When you fork
a child, the child gets a copy of all the parents file descriptors, but the file objects are not copied -- the file descriptors in the child refer to the same file object. So when you open
the read file and then fork
, the parent and child share a file object for that file, which means that when either one reads from the file, it advances the read location in the file, so when the other one reads from the file, it will get bytes from that advanced point rather than the start.
The net effect is that the bytes in the source file will be "split" between your parent and child -- each process will get some but not all of the bytes. Which bytes go to which depends on timing and is hard to predict.
To avoid this, you want to open
the source file after calling fork. This will result in opening the file twice (once in the parent and once in the child), thus creating two file objects to track the read location, and allowing parent and child to read the file independently.
CodePudding user response:
Even if you found a way of reading and writing to the same file at the same time, it is probably unwise and may lead to data corruption. If you really need two processes and really need to read and write to a.txt from both you can do it by opening reading/writing and closing the file each time you read/write data. This would be safe but the performance wouldn't be good.
If you're only reading from parent and child you can just open after the fork without issue so it is opened for read twice.
You can write to b.txt from the parent only and write to c.txt from the child only without issue by opening those files after the fork().
To communicate between parent and child process efficiently, you can use pipes, but the amount of data you can send in a pipe is not as large as in a file. Using a file for this purpose when a pipe would do the trick is probably bad practice.