zoukankan      html  css  js  c++  java
  • linux下多进程同时操作文件

    转自:https://blog.csdn.net/u011508527/article/details/46878205

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    centos crash debug
    go get Unknown SSL protocol error in connection to gopkg.in
    Tensorflow serving with Kubernetes
    Spring 集成 Swagger UI
    Docker Registry V2 Garbage Collection
    Docker Registry V2 with Nginx
    Zabbix磁盘性能监控
    Zabbix CPU utilization监控参数
    Windows挂载Gluster复制卷
    Redis持久化存储(三)
  • 原文地址:https://www.cnblogs.com/fnlingnzb-learner/p/13030070.html
Copyright © 2011-2022 走看看