分析fork后多进程对文件的共享

fork函数是建立一个新的进程做为原进程的子进程,建立的子进程和父进程存在不少的类似性,首先父子进程的虚拟存储空间的用户空间是相同的,是将父进程的拷贝给子进程。同时父子进程对文件的操做是共享方式。由于父进程的文件描述符表被拷贝给了子进程(具体的原理参虚拟存储器的内容,私有对象写时拷贝实现了父子进程之间造成相互独立的地址空间)。所以父进程打开的全部文件描述符都在子进程中保存了(每一个进程都有独立的描述符表)。因为全部的进程共享文件表、v-node表,因此父子进程的描述符表也是相同的,因此父子进程对文件是以共享的方式存在的。
 
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/wait.h>
 
int main()
{
        int fd;
        char c[3];
        /*打开文件foobar.txt,采用的是只读形式*/
        fd = open("foobar.txt",O_RDONLY,0);
 
         if(fork()==0)//子进程
        {
                read(fd,&c,2);/*读文件的一个字节到c中*/
                c[2]='\0';
                printf("c = %s\n",c);
                exit(0);
        /*子进程结束*/
        }
        /*下面是父进程的读操做*/
        wait(NULL);
        read(fd,&c,2);
        c[2]='\0';
        printf("c = %s\n",c);
        exit(0);
}
其中foobar.txt中的内容是foobar。
编译调试之后的结果是:
[gong@Gong-Computer cprogram]$ gcc -g fileshare2.c -o fileshare2
[gong@Gong-Computer cprogram]$ ./fileshare2
c = fo
c = ob
 
缘由分析:因为父子进程是以共享的方式控制已经打开文件的,所以对文件的操做也是相互影响的,所以读写文件的位置也会发生相应的改变。父(子)进程的文件读写位置会随着子(父)进程的文件读写位置改变而改变,由于此时改变的是文件表的文件位置项,而文件表是全部进程共享的,任何一个进程的修改都会影响到别的进程。可是父(子)进程对描述符的修改不会影响子(父)进程的描述符,由于close(fd)的操做只是改变文件表述符表中的内容,而该表是每一个进程相互独立的,所以不会改变其余进程的表。
相关文章
相关标签/搜索