Are write() calls guaranteed atomic?

Dan Nelson dnelson at allantgroup.com
Mon Jun 2 08:49:20 PDT 2003


In the last episode (Jun 02), Matthew Hagerty said:
> I'm writing a server that receives data via a named pipe (FIFO) and
> will always have more than one other process sending data to it, and
> I'm concerned with preventing data multiplexing.  The data coming in
> will be lines of text delimited with a newline, but the processes
> writing the data have no knowledge of the FIFO, they simply think
> they are writing to a file.  This being the case, the processes
> writing the data give no regard to PIPE_BUF and may send data in
> longer lengths (but probably never longer than 2K to 4K.)
> 
> Will the kernel ensure that the data write() will be delivered to the
> FIFO atomically even if the data is larger than PIPE_BUF, such that
> two or more successive read() calls will retrieve the data in order?

Pipes are always FIFO; it's part of their definition.  From SUSv3:

  A read on the file descriptor fildes[0] shall access data written to
  the file descriptor fildes[1] on a first-in-first-out basis.

To ensure that your writes don't get interleaved with writes from other
processes, you do need to limit your write sizes to PIPE_BUF or less
bytes:

  Write requests of {PIPE_BUF} bytes or less shall not be interleaved
  with data from other processes doing writes on the same pipe. Writes
  of greater than {PIPE_BUF} bytes may have data interleaved, on
  arbitrary boundaries, with writes by other processes, whether or not
  the O_NONBLOCK flag of the file status flags is set.

If you cannot modify the clients, try changing your server to create a
Unix domain socket instead of a named pipe (the clients shouldn't see
any difference).

-- 
	Dan Nelson
	dnelson at allantgroup.com


More information about the freebsd-hackers mailing list