Linux Unix对单个文件的读写是否进行了原子序列化?

Linux Unix对单个文件的读写是否进行了原子序列化?,linux,file,unix,Linux,File,Unix,我想知道对单个文件的写入是否以原子方式完成,即对同一文件的写入(“bla-bla”)和后续写入(“herp-derp”)不会导致交错,例如“bla-herp-bla-derp”。假设这些写操作发生在不同的进程或线程中,那么是什么决定了哪些先完成 另外,read()是否总是返回数据,以反映之前所有写入操作都已完全完成的文件状态(无论数据是否已实际写入磁盘)?例如,在写入(“herp derp”)之后,所有后续读取是否始终反映写入文件的完整数据,或者后续读取是否有时只反映“herp”而不反映“der

我想知道对单个文件的写入是否以原子方式完成,即对同一文件的写入(“bla-bla”)和后续写入(“herp-derp”)不会导致交错,例如“bla-herp-bla-derp”。假设这些写操作发生在不同的进程或线程中,那么是什么决定了哪些先完成

另外,read()是否总是返回数据,以反映之前所有写入操作都已完全完成的文件状态(无论数据是否已实际写入磁盘)?例如,在写入(“herp derp”)之后,所有后续读取是否始终反映写入文件的完整数据,或者后续读取是否有时只反映“herp”而不反映“derp”(或者有时根本不反映任何数据)?如果读写操作发生在不同的进程/线程中,该怎么办

我对并发文件访问策略不感兴趣。我只想知道读和写的确切功能。

分离
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是非原子的,这导致了这次提交-