Concurrency 是POSIX';读()和写()系统调用原子?
我试图实现一个基于数据结构(眨眼树)和算法的数据库索引,该算法由Lehman和Yao在年提出。在第2页中,作者声明: 磁盘按固定大小分区(物理页;在本文中,这些页对应于树的节点)这些是进程可以读取或写入的唯一单元。[emphasis mine](…) (…)允许进程锁定和解锁磁盘页。此锁授予该进程对该页面的独占修改权限;另外,一个进程必须锁定一个页面才能修改该页面。(…)锁定不会阻止其他进程读取锁定的页面。[emphasis mine] 我不完全确定我的解释是否正确(我不习惯阅读学术论文),但我认为从强调的句子中可以得出结论,作者的意思是读写一页的操作被认为是“原子的”,即如果一个过程a已经开始读(或写)一页,另一个进程B可能不会开始写入(或读取)同一页,直到A完成其读取(或写入)操作。当然,多个进程同时读取同一页面是一种合法的条件,因为有多个进程同时在完全不同的页面上执行任意操作(P页上的进程a、Q页上的进程B、R页上的进程C等)Concurrency 是POSIX';读()和写()系统调用原子?,concurrency,posix,b-tree,database-indexes,Concurrency,Posix,B Tree,Database Indexes,我试图实现一个基于数据结构(眨眼树)和算法的数据库索引,该算法由Lehman和Yao在年提出。在第2页中,作者声明: 磁盘按固定大小分区(物理页;在本文中,这些页对应于树的节点)这些是进程可以读取或写入的唯一单元。[emphasis mine](…) (…)允许进程锁定和解锁磁盘页。此锁授予该进程对该页面的独占修改权限;另外,一个进程必须锁定一个页面才能修改该页面。(…)锁定不会阻止其他进程读取锁定的页面。[emphasis mine] 我不完全确定我的解释是否正确(我不习惯阅读学术论文),但我
read()
和write()
系统调用在上述意义上是“原子”的吗?我可以依靠这些具有一些内部逻辑的系统调用来确定是否应该根据文件描述符的位置和要读取或写入的块的指定大小临时阻止特定的read()
或write()
调用吗我不相信你引用的文本暗示了任何类似的东西。它甚至没有提到
read()
或write()
或POSIX。事实上,read()
和write()
不能被认为是原子的。POSIX所说的唯一一件事是,如果写入的大小小于PIPE\u BUF
字节,那么write()
必须是原子的,甚至这只适用于管道
我没有阅读你引用的那篇文章的上下文,但听起来你引用的那篇文章是在陈述必须对实现施加的约束,以使算法正确工作。换句话说,它声明此算法的实现需要锁定
如何实现锁定取决于您(实现者)。如果我们正在处理一个常规文件和多个独立进程,您可以尝试fcntl(F_SETLKW)
样式的锁定。如果您的数据结构在内存中,并且您在同一进程中处理多个线程,则可能需要使用其他方法。答案:
无O_直接/文件标志\u无缓冲: 使用NTFS的Microsoft Windows 10:更新原子性=1字节 Linux 4.2.6和ext4:update atomicity=1字节 带ZFS的FreeBSD 10.2:更新原子性=至少1Mb,可能无限(*) O\u直接/文件\u标志\u无\u缓冲: Microsoft Windows 10 with NTFS:update atomicity=仅当页面对齐时最多4096字节,否则,如果文件\u FLAG\u WRITE\u关闭,则为512字节,否则为64字节。请注意,此原子性可能是PCIe DMA的一项功能,而不是(*)中设计的 Linux 4.2.6和ext4:update atomicity=至少1Mb,可能是无限(*)。请注意,早期带有ext4的Linuxes肯定没有超过4096字节,XFS当然曾经有自定义锁定,但看起来最近的Linux终于解决了这个问题 带ZFS的FreeBSD 10.2:更新原子性=至少1Mb,可能无限(*)
您可以在上看到原始的实证测试结果。结果由在所有平台上使用异步文件i/o编写的程序生成。注意,我们只在512字节的倍数上测试被撕裂的偏移量,所以我不能说512字节扇区的部分更新是否会在读-修改-写周期中被撕裂