本章主要介绍一些高级I/O,包括非阻塞I/O、文件记录锁、STREAMS、I/O多路转接、writev/readv、writen/readn以及存储映射。
1、非阻塞I/O:
- 对于write函数调用,在有些情况下(如数据不能被立即接受:管道中无空间、网络流控制),会产生阻塞;
- 对于read函数调用,在有些情况下(如数据不存在,如管道、终端设备和网络设备),会产生阻塞。
- 有时候不希望有此种阻塞,因此可以在open时,用O_NONBLOCK来指定文件的模式为非阻塞模式。也可以使用ioctl函数来设定对文件描述符的操作为非阻塞模式。
2、文件记录锁:有时对一个文件进行锁时只锁住其中的一部分区域,此时文件记录锁(字节范围锁)即可实现这种效果。
- fcntl函数:int fcntl (int fields, int cmd, struct flock *flockptr);其中flock结构包含了操作的锁定类型、锁定文件的区域、以及PID参数。
- 锁定隐含继承和释放:
- 继承:当用execl函数创建进程时,因为新进程和父进程具有相同的PID,因此锁是隐含继承的;
- 释放:当一个进程终止时,则进程建立的锁全部被释放;
- 解释:因为每把锁定标识号是PID,存放在文件的i节点当中。
- 数据可以顺流而下,也可以逆流而上,这取决于数据的传输方向;
- STREAMS消息:STREAMS是以消息的形式来传输数据的。消息通常分为三部分:消息类型、可选控制信息和可选择的数据,而控制部分和数据部分用相同数据结构表示,包含了maxlen、len、和buf;而消息类型分为M_DATA、M_PROTO和M_PCPROTO,而消息是自动产生的,putmsg和putpmsg用不同的参数会产生不同的消息类型。
- 写:write、putmsg、putpmsg(可以指定波段);
- 读:read、getmsg、getpmsg(可以指定波段);由于read只能读取数据,故需要对read模式进行设置(RNORM\RMSGN\RMSGD)
- select函数:int select(int masfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *restrict tvptr);
- FD_ISSET、FD_CLR、FD_SET、FD_ZERO
- poll函数,poll函数和select函数功能相似,只不过poll函数对于每一个文件描述符,用结构体去测试其状态。
6、writen和readn函数:用于固定读或写多少个字节
7、存储映射I/O:将磁盘文件与存储空间中的一个缓冲区相映射,对缓冲区进行操作就相当于对文件进行操作。
- void *mmap(void *addr, size_t len, int prot, int flag, int fields, off_t off);其中的flag可以指定为MAP_SHARED或MAP_PRIVATE。