Linux Unix对单个文件的读写是否进行了原子序列化?
我想知道对单个文件的写入是否以原子方式完成,即对同一文件的写入(“bla-bla”)和后续写入(“herp-derp”)不会导致交错,例如“bla-herp-bla-derp”。假设这些写操作发生在不同的进程或线程中,那么是什么决定了哪些先完成 另外,read()是否总是返回数据,以反映之前所有写入操作都已完全完成的文件状态(无论数据是否已实际写入磁盘)?例如,在写入(“herp derp”)之后,所有后续读取是否始终反映写入文件的完整数据,或者后续读取是否有时只反映“herp”而不反映“derp”(或者有时根本不反映任何数据)?如果读写操作发生在不同的进程/线程中,该怎么办 我对并发文件访问策略不感兴趣。我只想知道读和写的确切功能。分离Linux Unix对单个文件的读写是否进行了原子序列化?,linux,file,unix,Linux,File,Unix,我想知道对单个文件的写入是否以原子方式完成,即对同一文件的写入(“bla-bla”)和后续写入(“herp-derp”)不会导致交错,例如“bla-herp-bla-derp”。假设这些写操作发生在不同的进程或线程中,那么是什么决定了哪些先完成 另外,read()是否总是返回数据,以反映之前所有写入操作都已完全完成的文件状态(无论数据是否已实际写入磁盘)?例如,在写入(“herp derp”)之后,所有后续读取是否始终反映写入文件的完整数据,或者后续读取是否有时只反映“herp”而不反映“der
write()
调用是单独处理的,而不是作为单个原子写入事务处理的,当多个进程/线程写入同一文件时,完全可以交错处理。实际写入的顺序由调度器(内核进程调度器和线程库的调度器)决定
除非您另外指定(O\u DIRECT
open
标志或类似标志,如果支持),read()
和write()
对内核缓冲区进行操作,read()
将优先使用加载的缓冲区,而不是再次读取磁盘
注意,本地文件缓冲可能会使这一过程变得复杂;例如,
stdio
和iostreams
将在进程中将文件数据按块读取到一个缓冲区中,该缓冲区独立于内核缓冲区,因此不会看到从别处写入已在stdio
中缓冲的数据的write()
。同样,在输出缓冲区刷新之前,不会有任何实际的内核级输出,无论是自动刷新,还是手动刷新,都是由于fflush()
或C++的endl
(隐式刷新输出缓冲区)。Thx,你听起来好像知道你在说什么:)我觉得stdio的读/写是sys_write/sys_read的直接包装?不是这样吗?此外,linux文档中的这一点是什么意思:“POSIX要求在write()返回新数据后发生读取(2)。”单独的文件描述是否在内核中使用单独的读/写缓冲区?如果我在一个进程中读取,它是否可能反映从另一个进程写入写入缓冲区的数据?或者,无论在多个进程/线程中打开了多少描述,每个文件都始终有一个内核缓冲区?(顺便说一句,我使用“description”来表示打开文件的底层表示,而不是进程中用作句柄的“descriptor”编号,例如dup()为现有描述返回一个新的描述符)@Jegschemesch,这意味着如果您写入
数据,然后立即读取
,它总是读取新数据。答案取决于内核的细节。在大多数现代类Unix系统中,文件块在全局基础上进行缓冲;也就是说,无论有多少进程在给定文件上打开了多少文件描述符,缓冲都是由块地址完成的,并在所有进程之间共享。例外情况是,O\u DIRECT
,正如我前面提到的,或者访问原始设备而不是块设备(ls-l
分别显示c
或b
,而不是文件的-
或目录的d
)。此提交中的提交消息–表明write()
调用是原子的,不是吗?你的问题很搞笑,正是我要问的。lol…OP发布了一个后续问题,您可能对Linux内核感兴趣,题为write()上文件偏移量的更新等。I/O是非原子的,这导致了这次提交-