【问题标题】:How does one process see the write of another process immediately? [closed]一个进程如何立即看到另一个进程的写入? [关闭]
【发布时间】:2020-11-25 04:11:10
【问题描述】:

我编写了一个程序,其中一个进程将数据写入文件,而另一个进程从同一个文件中读取数据。伪代码如下:

write process:
    1. open file;
    2. write data to file;
    3. set true to flag;
    4. sleep infinity;

read process:
    1. open file;
    2. loop inifinity:
    3.   if flag:
    4.     read data from file;

我知道在 os 中文件的写入是如何工作的:

buffered file | unbuffered file
--- | flush ------- | write ---
    V               V
          os kernel
------------- | sync ----------
              V
            disk

所以我把我的问题分成三个具体的问题:

  • 在写入过程的第2步,如果我将缓冲文件(或直接写入非缓冲文件)写入操作系统内核,在写入过程设置标志后读取过程是否可以立即看到数据?

  • 在写过程的第2步中,如果我将文件中的数据从操作系统内核同步到磁盘,读过程可以在写过程设置标志后立即看到数据吗?

  • 如果我用线程替换进程,结果会一样吗?

【问题讨论】:

    标签: linux operating-system


    【解决方案1】:

    如果您使用 write 系统调用来写入数据,其他进程或线程应该会立即看到它。既然是正在运行的系统,那么数据是在缓冲区缓存中还是实际写入硬盘应该是无关紧要的。但是,如果您使用 fwrite 之类的标准库调用,则会出现数据在进程中被缓冲而其他进程无法立即看到的问题。因此,请避免使用库并直接使用 write 系统调用。只有当存在系统崩溃的风险时,才需要担心每次使用同步 I/O 的写入操作在写入调用中使用 O_DSYNC 或 O_SYNC 标志实际写入硬盘。

    【讨论】:

      【解决方案2】:

      所有三个问题的答案都是肯定的,每次在write(2) 之后执行read(2),数据都保证是可见的。从 POSIX 1003.1-2008:

      如果可以(通过任何方式)证明文件数据的read() 发生在数据的write() 之后,则它必须反映write(),即使调用是由不同的进程进行的。

      这确实需要符合 POSIX 的文件系统;正如 Linux 手册页所指出的,并非所有文件系统都符合 POSIX。 POSIX 还需要 pwrite(2)writev(2) 的这种行为,因为它们被定义为“等效于 write()”,但有特定的例外。

      在您的情况下,它还假定您的缓冲文件在后台调用write(2)(或其他相关函数之一);我相信 glibc 的 stdio 库也是如此。

      【讨论】:

      • 谢谢。我通过你的回答找到了reference
      猜你喜欢
      • 1970-01-01
      • 2012-07-05
      • 2015-04-28
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 2020-09-27
      • 2012-11-07
      • 1970-01-01
      相关资源
      最近更新 更多