热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

linux下多进程同时操作文件

我们都知道多进程同时操作文件会出现问题,但是具体会出现什么问题呢?不知道大家有没有仔细研究过,今天我就带大家一起来研究一下。在操作文件之前,很有必要了解一下内核中文

        我们都知道多进程同时操作文件会出现问题,但是具体会出现什么问题呢?不知道大家有没有仔细研究过,今天我就带大家一起来研究一下。

     在操作文件之前,很有必要了解一下内核中文件的存储和访问方式:

      这张图摘自《APUE》,我觉得画的很好,所以就没有自己再画了。

       从图中能够看出每个进程都有自己独立的一个进程表项,由文件指针指向文件表项;在文件表项中两个很重要的东西:状态标志和当前文件偏移量,问什么说它很重要,因为在多进程写文件出错时,一般都是由文件偏移量引起的(这个后面会讲到);然后由V节点指针指向一个V节点表(关于i节点我会在另外的博客中阐述)

       第一种情况:父子进程同时写一个文件


      父进程再用fork函数创建子进程的时候,会把自己的上下文环境拷贝一份复制到子进程的内存空间中,这里当然包括进程表。所以子进程的进程表和父进程的是一模一样的,它们指向的是同一个文件表,上面讲到过,当前偏移量会引起文件操作错误。

      对于这个文件偏移量,有几点需要搞清楚:在用open函数打开文件时如果没有加上O_APPEND标志,那么这个文件表的文件偏移量为0;加上的话,它会把V节点中的当前文件长度赋给文件偏移量;写完文件之后(没有关闭文件描述符),文件长度会变化,相应的当前偏移量也随着文件长度的变化而变化。这里需要注意,是写完一个文件之后(也就是write函数执行完之后),便宜量才会改变。

     到这里的话,基本上就清楚了:如果写操作是一个原子操作的话(可以用pwrite实现),那么父子进程写同一个文件不会出现任何问题;如果不是原子操作的话,有可能在父进程的write函数没有返回之前又执行了子进程的write函数,由于当前文件偏移量没有改变,所以会覆盖掉原先内容。

      第二种情况:非父子进程写同一个文件

     

       对于非父子类型的多进程写同一个文件,其情况又是另外一回事了:

        进程各自有各自的进程表,至于为什么要有各自的进程表而不是共享一个进程表?可以这么想:各个进程打开文件的标志可能会不一样,有的可能只读、只写、或者读写方式,这样的话,它们中的内容肯定会不一样。

       对于fd0,假设它刚刚写完一个文件,fd0指向的文件表中的当前偏移量改变了,但是fd1中的偏移量没有改变,这就造成fd1在写文件时会覆盖fd0写入文件的内容。

      具体情况大家可以在自己的机器上试验一下。


       


推荐阅读
author-avatar
爵士723
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有