如果一个进程执行大小(和对齐)S的write()(例如8KB),那么另一个进程是否可以执行读取(也是大小和对齐S和同一文件)的混合旧数据和新数据?
写入过程为每个数据块添加校验和,我想知道是否可以使用读取过程来验证后台的校验和。如果读者可以看到部分写入,那么它将错误地指示损坏。
这里适用哪些标准或文件?有没有一种可移植的方法来避免问题,最好不要引入大量锁定?
答案 0 :(得分:3)
当一个函数保证完成而没有任何其他进程/线程/任何东西看到处于半完成状态的东西时,它被称为 atomic 。它要么已经发生过,也没有发生过,没有任何一种方式。虽然我不能与Windows交谈,但POSIX中的文件操作很少(这是Linux / BSD / etc试图坚持的),这些操作保证是原子的。阅读和写作不保证是原子的。
虽然你不太可能将2个字节写入文件,而另一个进程只能看到写入的那些字节中的一个,如果运气不好,你的写入跨越内存中的两个不同的页面而VM系统必须做一些事情准备第二页,你可能会在第二个过程中看到一个字节没有另一个字节。通常,如果文件中的页面对齐,它们将在内存中,但您再也不能依赖它。
Here's a list某人是由POSIX中的原子构成的,这很短,我不能保证它的真实性。 (我想不出为什么没有列出unlink,例如)。
我还提醒您不要测试看起来有效并运行的内容,当您开始通过网络文件系统(Unix上的NFS或Windows中的SMB安装)访问文件时,很多事情似乎都是原子不再存在。
如果您希望在第一个进程正在写入文件时让第二个进程计算校验和,您可能需要在两者之间打开一个管道,让第一个进程将管道中的所有内容的副本写入校验和过程。这可能比处理锁定更快。