开发者

When using unix pipes (in C) does the OS balance every write() with a read() or does it balance the total number of bytes?

开发者 https://www.devze.com 2023-04-10 08:55 出处:网络
for example, i want to get an array of 4 ints from child to parent. parent calls read(apipe, buf, sizeof(int)*4);

for example, i want to get an array of 4 ints from child to parent. parent calls

read(apipe, buf, sizeof(int)*4);

child calls

for(int i=0; i<4;i++)
    write(bpipe, &array[i], sizeof(int));

does this do what I intend (开发者_高级运维getting 4 ints to the parent) or does the parent simply get the first integer?

I tried searching for this answer elsewhere, but either I don't know how to search or this is too subtle (or on the other hand too seemingly obvious) for literature to dwell on it much.

EDIT: To clarify further, I was trying to write a 4-part message and read all 4 parts in one read(). See comments on accepted answer.


read and write work with bytes, not messages. For details of how they behave with pipes, see the documentation in POSIX:

  • http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
  • http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

In your code, I think the read should always get 4 ints, due to:

Upon successful completion, where nbyte is greater than 0, read() shall mark for update the last data access timestamp of the file, and shall return the number of bytes read. This number shall never be greater than nbyte. The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal, or if the file is a pipe or FIFO or special file and has fewer than nbyte bytes immediately available for reading. For example, a read() from a file associated with a terminal may return one typed line of data.

There will always be 4 ints available for reading, because 4*sizeof(int) < PIPE_BUF and thus writes of this size are atomic.

It's possible that the allowance for read to return a short read when interrupted by a signal could come into play, but that should not be able to happen (in the real world, at least) when sufficiently many bytes are available immediately.


The Definitions section of POSIX says that a pipe is identical to a FIFO except it has no entry in the file system.

From the POSIX definition for write():

Write requests to a pipe or FIFO shall be handled in the same way as a regular file with the following exceptions:

  • There is no file offset associated with a pipe, hence each write request shall append to the end of the pipe.

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

From the POSIX definition for read():

The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal, or if the file is a pipe or FIFO or special file and has fewer than nbyte bytes immediately available for reading.

Later, in the informative (non-normative) section of read() entry, it says:

The standard developers considered adding atomicity requirements to a pipe or FIFO, but recognized that due to the nature of pipes and FIFOs there could be no guarantee of atomicity of reads of {PIPE_BUF} or any other size that would be an aid to applications portability.


So, the standard implies that if all 4*sizeof(int) bytes are available when the read() is issued, then all 4*sizeof(int) bytes will be returned, but if only 1, 2 or 3 of the write() calls have completed, then the read() will not wait for the fourth to finish; it will return with a short read.

Consequently, your reading code must allow for 'short reads' which are non-erroneous; they simply mean that not all the required data was present.


It should read all four. If it doesn't, the error from read should indicate why. The number of writes and reads doesn't need to match.

0

精彩评论

暂无评论...
验证码 换一张
取 消