在Linux上,如果一个脚本正在读取一个(大)文件,而另一个脚本试图写入同一个文件,那么这两个操作是否会成功,以便第一个脚本读取未损坏的数据(因为inode)?(假设我使用的是file_get_contents和file_put_contents)
发布于 2013-12-01 16:52:06
“最正确”的答案是:No。
虽然小的打印要详细一点:这两个操作都会成功,而且在最严格的措辞意义上,您永远不会看到损坏的数据。但是,您看到的数据可能不一致。这意味着,如果你写了"ABC“,那么写"AB”可能会在某人阅读之前实现(最后一点数据将是之前文件中的任何内容),但是"ABC“永远不会被损坏到"pnt”或"CDQ“中。
此外,如果两个进程同时写入,则有可能在实现另一个进程之前只实现一个进程的一部分。例如,同时编写"ABCDEF“和"123456”可能会导致"A2C4E6“存储在缓冲区缓存中,并随后存储在磁盘上。它还可能导致"ABCDEF“或"123456”。第三个进程可以同时读取任何可能的组合。
读写通常不能保证是原子的。readv和writev系统是例外的,因为它们保证是原子的(至少在文件上)。然而,这不是“正常”写的用法。
此外,库级缓存通常会发生,因此除了缓冲区缓存中的读和写不一定是原子的之外,同时读取和写入的两个进程对于文件的内容可能有非常不同的想法。
附加到文件(非并发)和并发读取通常是“安全的”。不是所有的数据在您阅读时都是可见的,但是无论您写什么,都会以您编写它的方式结束。
请注意,一些PHP函数将在某些体系结构上使用文件映射,这将使事情进一步复杂化。
作为对编辑的回应:、file_get_contents和file_put_contents正是前面提到的在某些体系结构上使用内存映射的一些函数。
它没有具体说明具体的架构,但是Linux是一个相当安全的赌注。
现在内存映射的问题是并发访问文件的两个进程实际上是同时访问相同的物理内存。这意味着,在没有显式同步的情况下,读写仍然是而不是原子。
此外,您也没有正式的保证(尽管实现实际上保证了这一点,因为Linux有一个统一的虚拟内存系统),除非调用了msync,否则内存视图对应于外部可观察的磁盘上表示。这意味着在理论上(虽然不是在实践中),使用普通读写(不使用内存映射)的不同进程可能会看到完全不同的东西。
https://stackoverflow.com/questions/20314386
复制相似问题