This chapter covers numerous topics and functions that we lump under the term advanced I/O : nonblocking I/O, record locking, I/O multiplexing (the select and poll functions), asynchronous I/O, the readv and writev functions, and memory-mapped I/O (mmap).

1 Nonblocking I/O

参考IO - 同步,异步,阻塞,非阻塞

2 Record Locking

Record locking is the term normally used to describe the ability of a process to prevent other processes from modifying a region of a file while the first process is reading or modifying that portion of the file. Under the UNIX System, ‘‘record’’ is a misnomer; the UNIX kernel does not have a notion of records in a file. A better term is byte-range locking, given that it is a range of a file (possibly the entire file) that is locked.

demo可以参考Linux进程同步之记录锁和书中示例。对于像锁的隐含继承与实现这些细节问题可参考书籍。

3 I/O Multiplexing

参考IO - 同步,异步,阻塞,非阻塞

  • select and pselect Functions
  • poll Function

4 Asynchronous I/O

参考IO - 同步,异步,阻塞,非阻塞

5 readv and writev Functions

The readv and writev functions let us read into and write from multiple noncontiguous buffers in a single function call. These operations are called scatter read and gather write.

1
2
ssize_t readv(int fd, const struct iovec *iov, int iovcnt); 
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

The second argument to both functions is a pointer to an array of iovec structures:

1
2
3
4
struct iovec {
void *iov_base; /* starting address of buffer */
size_t iov_len; /* size of buffer */
};

The number of elements in the iov array is specified by iovcnt.Figure 14.22 shows a diagram relating the arguments to these two functions and the iovec structure.

6 readn and writen Functions

Pipes, FIFOs, and some devices—notably terminals and networks—have the following two properties:

  1. A read operation may return less than asked for, even though we have not encountered the end of file. This is not an error, and we should simply continue reading from the device.
  2. A write operation can return less than we specified. Again, it’s not an error, and we should continue writing the remainder of the data.

Generally, when we read from or write to a pipe, network device, or terminal, we need to take these characteristics into consideration. We can use the readn and writen functions to read and write N bytes of data, respectively, letting these functions handle a return value that’s possibly less than requested. These two functions simply call read or write as many times as required to read or write the entire N bytes of data.

1
2
ssize_t readn(int fd, void *buf, size_t nbytes); 
ssize_t writen(int fd, void *buf, size_t nbytes);

7 Memory-Mapped I/O

Memory-mapped I/O lets us map a file on disk into a buffer in memory so that, when we fetch bytes from the buffer, the corresponding bytes of the file are read. Similarly, when we store data in the buffer, the corresponding bytes are automatically written to the file. This lets us perform I/O without using read or write.