#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
char str[11]={0};
int main(int argc, char ** argv)
{
int fd = open("test.txt",O_RDWR);
if(fork() == 0){
ssize_t cnt = read(fd,str,10);
printf("Child process:%s\n",str);
}
else{
ssize_t cnt = read(fd,str,10);
printf("Parent process:%s\n",str);
}
printf("read over\n");
close(fd);
return 0;
}
可以发现,两个进程读到的内容并不一样,这是为什么呢?fork出来的进程用的资源不是父进程的一个拷贝吗?
实际上,这跟进程的PCB,也就是struct task_struct有关,进程打开的文件用struct file_struct *files表示,这实际是一个指针。在fork出子进程后,这个指针也会被copy到子进程的struct task_struct对象中,也就是父进程和子进程的*files是一样的。也就是使用了指向同一个文件对象的指针,再考虑到读取文件时一般加锁了。所以父进程读完后,会修改offset,而子进程读取数据的时候,是基于修改后的offset的。就会造成了上述问题。
那么,对于写呢?
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
char str[11]={0};
char str1[6] = "hello";
char str2[6] = "world";
int main(int argc, char ** argv)
{
int fd = open("test.txt",O_RDWR);
if(fork() == 0){
// ssize_t cnt = read(fd,str,10);
write(fd,str1,6);
printf("Child process:%s\n",str);
}
else{
// ssize_t cnt = read(fd,str,10);
write(fd,str2,6);
printf("Parent process:%s\n",str);
}
printf("write over\n");
close(fd);
return 0;
}
可以发现,也是同样的效果,共用了同一个files,造成先后顺序写入内容。
这说明了,使用fork()得到的父子进程在操作同一个文件的时候,并不能像两个独立进程操作一个文件一样(如果两次写,只保留一份,后面的会把前面的冲掉)