What happens if a write system call is called on s

2019-01-24 21:53发布

Does the OS handle it correctly?

Or will I have to call flock()?

5条回答
Explosion°爆炸
2楼-- · 2019-01-24 22:11

Yes of course it will work correctly. It won't crash the OS or the process.

Whether it makes any sense, depends on the way the application(s) are written an what the file's purpose is.

If the file is opened by all processes as append-only, each process (notionally) does an atomic seek-to-end before each write; these are guaranteed not to overwrite each others' data (but of course, the order is nondeterministic).

In any case, if you use a library which potentially splits a single logical write into several write syscalls, expect trouble.

查看更多
疯言疯语
3楼-- · 2019-01-24 22:18

Although the OS won't crash, and the filesystem won't be corrupted, calls to write() are NOT guarenteed to be atomic, unless the file descriptor in question is a pipe, and the amount of data to be written is PIPE_MAX bytes or less. The relevant part of the standard:

An attempt to write to a pipe or FIFO has several major characteristics:

  • Atomic/non-atomic: A write is atomic if the whole amount written in one operation is not interleaved with data from any other process. This is useful when there are multiple writers sending data to a single reader. Applications need to know how large a write request can be expected to be performed atomically. This maximum is called {PIPE_BUF}. This volume of IEEE Std 1003.1-2001 does not say whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that writes of {PIPE_BUF} or fewer bytes shall be atomic.

[...]

As such, in principle, you must lock with simultaneous writers, or your written data may get mixed up and out of order (even within the same write) or you may have multiple writes overwriting each other. However, there is an exception - if you pass O_APPEND, your writes will be effectively atomic:

If the O_APPEND flag of the file status flags is set, the file offset shall be set to the end of the file prior to each write and no intervening file modification operation shall occur between changing the file offset and the write operation.

Although this is not necessarily atomic with respect to non-O_APPEND writes, or simultaneous reads, if all writers use O_APPEND, and you synchronize somehow before doing a read, you should be okay.

查看更多
Juvenile、少年°
4楼-- · 2019-01-24 22:19

write (and writev, too) guarantee atomicity.

Which means if two threads or processes write simultaneously, you do not have a guarantee which one writes first. But you do have the guarantee that anything that is in one syscall will not be intermingled with data from the other one.

Insofar it will always work correctly, but not necessarily in the way you expect (if you assume that process A comes before process B).

查看更多
干净又极端
5楼-- · 2019-01-24 22:19

Of course the kernel will handle it correctly, for the kernel’s idea of correctness — which is by definition correct.

If you have a set of coöperating flockers, then you can use the kernel to queue everyone up. But remember that flock has nothing to do with I/O: it will not stop someone else from writing the file. It will at most only interfere with other flockers.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-24 22:27

write(), writev(), read(), readv() can generate partial writes/reads where the amount of data transferred is smaller than what was requested.

Quoting the Linux man page for writev():

Note that is not an error for a successful call to transfer fewer bytes than requested

Quoting the POSIX man page:

If write() is interrupted by a signal after it successfully writes some data, it shall return the number of bytes written.

AFAIU, O_APPEND does not help in this regard because it does not prevent partial writes: it only ensures that whatever data is written is appended at the end of the file.

See this bug report from the Linux kernel:

A process is writing a messages to the file. [...] the writes [...] can be split in two. [...] So if the signal arrives [...] the write is interrupted. [...] this is perfectly valid behavior as far as spec (POSIX, SUS,...) is concerned

FIFOs and PIPE writes smaller than PIPE_MAX however are guaranteed to be atomic.

查看更多
登录 后发表回答