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