Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
481 views
in Technique[技术] by (71.8m points)

linux - Are Unix reads and writes to a single file atomically serialized?

I'd like to know if the writes upon a single file get done atomically such that write("bla bla") and a subsequent write("herp derp") to the same file never results in interleaving, e.g. "bla herp bla derp". Assuming these writes happen in different processes or threads, what governs which gets done first?

Also, does a read() always return data reflecting the file in a state of all previous writes fully completed (whether the data has been actually written to disk or not)? For example, after write("herp derp"), will all subsequent reads always reflect the full data written to the file, or will a subsequent read sometimes reflect only "herp" but not "derp" (or sometimes reflect none of the data at all)? What if the reads and writes occur in different processes/threads?

I'm not interested in concurrent file access strategies. I just want to know what read and write do exactly.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Separate write() calls are processed separately, not as a single atomic write transaction, and interleaving is entirely possible when multiple processes/threads are writing to the same file. The order of the actual writes is determined by the schedulers (both kernel process scheduler, and for "green" threads the thread library's scheduler).

Unless you specify otherwise (O_DIRECT open flag or similar, if supported), read() and write() operate on kernel buffers and read() will use a loaded buffer in preference to reading the disk again.

Note that this may be complicated by local file buffering; for example, stdio and iostreams will read file data by blocks into a buffer in the process which is independent of kernel buffers, so a write() from elsewhere to data that are already buffered in stdio won't be seen. Likewise, with output buffering there won't be any actual kernel-level output until the output buffer is flushed, either automatically because it has filled up or manually due to fflush() or C++'s endl (which implicitly flushes the output buffer).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...