UNIX环境高级编程_文件IO_共享文件操作

这篇笔记记录下,多进程(包括父子进程)操作同一个文件,或者同一个文件被同一个进程多次打开时的情况,总是傻傻分不清,必须记录一下了。

1 文件IO_共享文件

分下面四种情况记录。

情况1:同一进程多次open同一个文件

在同一个进程中多次open打开同一文件时,文件描述符不可能相同,因为同一个文件描述符池中某个文件描述符被占用,在close之前,该fd无法再次被使用。
在一个进程中,两次打开同一个文件,对应的代码如下:
在这里插入图片描述
通过实验发现,hello会被world覆盖,具体原因如下:
在这里插入图片描述
每个文件描述符都对应一个文件表,因为打开同一个文件,所以每个文件表V节点指针指向相同的V节点。每个文件描述符fd指向的文件表中有自己的“文件位移量”,新创建的文件,所以文件位移量是0,从0开始写,每write一次(clase()之后),文件偏移量增加写入的字节数,如果文件偏移量超出了当前文件长度,则用文件位移量更新当前文件长度。
在上面代码中,他们写的位置重重复了,所以hello会被world覆盖。
怎样解决上面问题呢?每次都加上O_APPEND,即可解决,其原理如下:当设置A_APPEND后,每次执行写操作时,文件表项中的当前文件偏移量首先会被设置为i节点表项中的文件长度,这就使得每次写入数据都会被追加到文件的末尾处。

情况2:多个进程共享操作同一个文件

不同进程打开同一个文件时候,各自使用的文件描述符表可能相等,本例子中相等。之所以相同,因为不同的进程有独立的文件描述符池,都是0-1023的范围,打开一个文件时候,首先会从最小的开始分配。实验代码如下:
在这里插入图片描述
在这里插入图片描述
单个进程打开文件两次与两个进程同时打开文原理相同,都指向了相同的V节点,所以也会出现覆盖的情况。同样的解决方法:指定A_Append标志,写操作时候,使用文件长度去更新文件位移量。保证了各自操作时,都在文件的末尾操作,就不会出现覆盖的情况。

情况3: 父子进程共享同一文件

父子进程共享文件和情况2中的多进程共享文件的原理相同,出现覆盖的原因相同。

	int main()
{
	pid_t ret = 0;
	ret = fork();
	if (ret > 0) // parent pid
	{
		int fd = 0;
		fd = open("./file.txt ",O_RDWR|O_CREAT,0664);
		write(fd,"hello\n",6);
	}
	else if(ret == 0) // child pid
	{
		int fd = 0;
		fd = open("./file.txt ",O_RDWR|O_CREAT,0664);
		write(fd,"world\n",6);
	}

	//while(1);
	return 0;
}

在这里插入图片描述
子进程和父进程指向相同的V节点表,它们拥有各自的独立的文件读写位置,刚开始都是0开始写,又会出现情况2中的覆盖,如果不想相互覆盖,需要加O_APPEND标志。

情况4: fork之前打开文件,会出现什么情况?

代码如下:

int main()
{

	pid_t ret = 0;
	
	int fd = 0;

	fd = open("./file.txt ",O_RDWR|O_CREAT|O_APPEND,0664);

	ret = fork();
	if (ret > 0) // parent pid
	{
		write(fd,"hello\n",6);
	}
	else if(ret == 0) // child pid
	{
		write(fd,"world\n",6);
	}

	//while(1);
	return 0;
}

上面代码中情况如下:
子进程会继承父进程已经打开的文件描述符,所以子进程和父进程的fd都指向了相同的文件表。由于共享相同的文件表,所以父子进程拥有共同的读写位置,不会出现写覆盖的情况。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值