Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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.

like image 494
Jegschemesch Avatar asked Mar 05 '11 01:03

Jegschemesch


1 Answers

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).

like image 159
geekosaur Avatar answered Oct 24 '22 11:10

geekosaur