What happens if a write system call is called in one file by two different processes at the same time?

Is the OS working correctly?

Or do I need to call flock ()?

+3
c linux system-calls operating-system
Aug 29 '11 at 9:59 a.m.
source share
5 answers

Although the OS will not crash and the file system will not be damaged, write() calls will NOT be guarenteed to be atomic unless the file descriptor is a pipe and the amount of data to be written is PIPE_MAX bytes or less. Relevant part of the standard :

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

  • Atomic / non-atomic: A record is atomic if the entire amount recorded in one operation does not alternate with data from any other process. This is useful when multiple authors send data to a single reader. Applications should know how big a write request can be expected atomically. This maximum is called {PIPE_BUF}. This volume of IEEE Std 1003.1-2001 does not indicate whether write requests for more than {PIPE_BUF} bytes are atomic, but requires that records {PIPE_BUF} or fewer bytes be atomic.

[...]

Thus, in principle, you should block concurrent writers, or your written data may mix up and fail (even within the same record), or you may have many records overwriting each other. However, there is an exception - if you pass O_APPEND , your entries will be effectively atomic:

If the O_APPEND flag of the file status flags is set, the file offset must be set to the end of the file before each write, and there must be no intermediate file change operation between changing the file offset and the write operation.

Although this is not necessarily atomic with respect to non-t22> writes or simultaneous reading, if all authors use O_APPEND and you somehow synchronize before doing read , you should be fine.

+10
Aug 30 2018-11-11T00:
source share

write (and writev too) guarantee atomicity.

This means that if two threads or processes are recorded at the same time, you do not have the guarantee that you record first. But you have a guarantee that everything that is in one syscall will not mix with data from another.

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

+2
Aug 29 '11 at 10:12
source share

Of course, the kernel will process it correctly, since the correctness is correct for the kernel.

If you have a set of cooperating flockers, you can use the kernel for each queue. But remember, the pack has nothing to do with I / O: this will not stop anyone else from writing the file. This will be nothing more than interfering with other flockers.

+1
Aug 29 2018-11-21T00:
source share

Yes, of course, it will work correctly. This will not cause the OS or process to crash.

Whether any meaning makes sense depends on how the application (s) are written, what the purpose of the file is.

If the file is opened by all processes as append-only, each process (in theory) performs atomic processing until the end of each record; they are guaranteed not to overwrite each other's data (but, of course, the order is non-deterministic).

In any case, if you are using a library that potentially splits one logical record into several system calls, expect problems.

+1
Aug 30 '11 at 10:01
source share

write() , writev() , read() , readv() can generate partial write / read, where the amount of data transferred is less than the requested.

Setting the Linux man page for writev() :

Please note that this is not an error for a successful call to transfer fewer bytes than requested

Indication of the POSIX manual page:

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

AFAIU, O_APPEND does not help in this regard, because it does not prevent partial recording: it only ensures that all recorded data is added at the end of the file.

See this bug report report from the Linux kernel :

The process writes messages to a file. [...] records [...] can be divided into two parts. [...] So, if a signal arrives [...], recording is interrupted. [...] this is a perfectly acceptable behavior, since the specification (POSIX, SUS, ...) concerns

FIFO and PIPE are written less than PIPE_MAX , but are guaranteed to be atomic.

0
Jan 02 '17 at 15:18
source share



All Articles