分析fork后多进程对文件的共享
2016-02-19 12:55
197 查看
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)的操作只是改变文件表述符表中的内容,而该表是每个进程相互独立的,因此不会改变其他进程的表。
#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)的操作只是改变文件表述符表中的内容,而该表是每个进程相互独立的,因此不会改变其他进程的表。
相关文章推荐
- 基于openssl的https服务配置
- Java 入门 之 Socket 与 聊天室项目基础知识
- 如何确定DM9000网卡的地址
- 经常使用算法之贪心
- 多进程共享文件
- vector容器与iterator迭代器
- Git常用命令备忘
- IOS中 Block简介与用法
- HDU 1950 Bridging signals (LIS)
- 面向对象知识二
- HDU 1523 Decoding Morse Sequences(DP)
- windows 显示smb分享成功,其他电脑却无法读取该分享原因
- CentOS 6.7下php5+安装redis扩展组件
- MPEG-7描述子(0)——颜色空间
- 【SPOJ-KNJIGE】KNJIGE【思维】【贪心?】
- web旋转式
- js || 运算符 config = config || {};
- PL/SQL教程之八:触发器
- java.util.LinkedHashMap cannot be cast to
- 并发