Linux内核中文件的数据结构和原子操作

Linux系统支持在不同进程间共享打开文件。内核为所有的I/O创建了3种数据结构表示打开文件,它们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。

  1. 每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述符表。
  2. 内核为所有打开文件维持一张文件表。包含了文件状态(读,写等),文件偏移量,指向i节点的指针。
  3. 每打开一个文件,都有一个i节点,它包含了文件类型和对该文件进行各种操作函数的指针。
同一进程打开不同文件的内核数据结构

 这个图本来描述的是UNIX操作系统的,在Linux中没有这个V节点,而是采用了一个与文件系统相关的i节点和一个与文件系统无关的i节点。图中描述的是分别从标准输入,标准输出,标准出错各自打开一个文件。

文件系统:文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。常见的文件系统有FAT,NTFS,ext2,ext3,ext4等。Linux的VFS处理了不同文件系统之间的统一管理。

多个进程打开同一文件

 每个进程都会获得自己的文件表,因为这可以使每个进程都有自己的对该文件的当前偏移量。但是这些文件表对于指定这个文件指向的是同一个v节点表。在fork后会发生的情形是多个文件描述符指向同一文件表项。此时,父子进程各自的每一个文件描述符共享同一个文件表项。这样的数据结构在多个进程读取同一文件的时候,是没有问题的。但是在多个进程写文件的时候,则可能产生难以预料的结果。这涉及到原子操作。

原子操作:由多步组成的操作,如果该操作是原子操作,那么它一定是连续执行知道执行完毕,期间不能被打断,要么就一步也不执行。

考虑有A,B两个进程同时打开同一个文件并写人内容。此时的数据结构和上图一样。每个进程都有自己的文件表,但是共享一个V节点。假设A进程现在写入100字节的内容。这时候,内核切换进程到B,B执行写入操作,写入了200字节的内容。这个时候,A进程写入的内容就被B进程写入的内容给覆盖掉了。并且文件长度变为200。(假设A,B进程初始化的文件偏移量为0,那么,B写入的时候,当前文件偏移量就是0,这就导致覆盖了A进程写入的内容。)Unix操作系统提供了一个原子操作的方法,那就是打开文件的时候设置O_APPEND标志。这样做可以使得内核在每次写操作之前将进程的当前偏移量设置到该文件的末尾。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值