据我了解,或多或少,所有系统都将对磁盘的写入作为对扇区的原子写入(通常为512或4096字节)。但是阅读呢?
即如果我有一个使用read(2)命令顺序读取文件的进程,那么在我完成对整个扇区的读取之前,是否有可能覆盖该扇区,或者整个扇区是否通过原子操作复制到内存中? >
以玩具为例;我有一个制作人,其中有mmap
:一个文件。该生产者的任务是在第一个扇区的某个位置写字母“ A”,然后将其移动到仍位于第一个扇区的另一个位置。由于生产者不知道何时将内存写入磁盘,因此请确保始终将“ A”写入新地址,然后再将其从旧地址中删除。因此,当查看磁盘上的文件时,可能存在2个“ A”,但永远不会小于1。但是请考虑以下情况:读取一个扇区不是原子的(例如,当使用另一个mmap
和{ {1}}?),那么有可能发生这样的情况:当使用者进程开始读取文件时,“ A”位于该扇区的后半部分,但是当使用者进程到达该扇区的第二部分时,一个新的(原子)对该扇区的写操作发生在“ A”移至该扇区的前半部分时。如果消费者继续阅读该行业的后半部分,则在该行业的任何地方都看不到任何“ A”。使用MAP_SHARED
时仍然有风险吗?
答案 0 :(得分:1)
实际上,NAND闪存,硬盘和CD-ROM将成为原子读取扇区,因为硬件无法同时从同一块读取和写入。此外,它们存储每个扇区的校验和,因此,任何撕裂的写入都将被作为读取错误丢弃。
但是,这对您而言都不重要,因为read/write/mmap
在VFS上运行,而不是直接在设备上运行。当您从read
页访问mmap
时,会得到该页的简单非原子副本,并且实际上可能没有显示“ A”。