2011-12-19 第十四章 高级I/O
第一节 引言
1,高级I/O包括:
非阻塞I/O
记录锁
系统V流机制
I/O多路转接
readv和writev函数
存储映像I/O(mmap)
第二节 非阻塞I/O
1,低速系统调用是可能会使进程永远阻塞的一类系统调用。
2,虽然读写磁盘文件会使调用者在短暂时间内阻塞,但并不能将与磁盘I/O有关的系统调用视为“低速”。
3,对于一个给定的描述符有两种方法对其指定非阻塞I/O:
a,如果调用open获得描述符,则可指定O_NONBLOCK标志
b,对于已经打开的一个描述符,则可调用fcntl,由该函数打开O_NONBLOCK文件状态标志。
4,POSIX.1要求,对于一个非阻塞的描述符如果无数据可读,则read返回-1,并且errno被设置为EAGAIN。
5,文件状态标志的更改影响同一文件表项的所有用户,但与通过其他文件表项对同一设备的访问无关。
第三节 记录锁
1,记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以阻止其他进程修改同一文件区。
2,fcntl记录锁的基本规则是:多个进程在一个给定的字节上可以有一把共享的读锁,但是在一个给定的字节上只能有一个进程独用一把写锁。进一步而言,如果在一个给定的字节上已经有一把或多把读锁,则不能在该字节上再加写锁;如果一个字节上已经有一把独占性的写锁,则不能对它再加任何的读锁。
3,上面说明的兼容性规则适用于不同进程提出的锁请求,并不使用于单个进程提出的多个锁请求。
4,记录锁的自动继承和释放有三条规则:
a,当一个进程终止时,它锁建立的锁全部释放;任何时候关闭一个描述符时,该进程通过这一描述可以引用的文件上的任何一把锁都被释放。
b,由fork产生的子进程不继承父进程锁设置的锁。
c,在执行exec后,新程序可以继承原执行程序的锁。
5,在接近文件尾端加锁或解锁时需要特别小心。
6,建议性锁对非合作进程是不起作用的。
7,linux中,使用强制性锁需要在文件系统挂载的时候mount命令加上_omand选项以打开该机制。
8,对于一个特定文件打开其设置组ID位,并关闭其组执行位,则对该文件开始了强制性锁机制。
第四节 STREAMS(看不懂啊!)
1,STREAMS是系统V提供的构造内核设备驱动程序和网络协议包的一种通用方法。
2,流在用户进程和设备驱动程序之间提供了一条全双工通路。流无需和实际硬件设备直接会话,流也可以用来构造伪设备驱动程序。
3,在Linux中,STREAMS子系统是可用的,但是用户必须自行将该子系统安装到系统中,通常它默认为不包括在系统中。
第五节 I/O多路转接
1,I/O多路转接:先构造一张有关描述符的列表,然后调用一个函数,直到这些描述符中的一个已准备好进行I/O操作时,该函数才返回。在返回时,它告诉进程哪些进程已经好可以进行I/O。这些函数即select和pselect函数。
2,poll函数类似于select,但是其程序员接口则有所不同。
3,虽然poll函数可用于任何类型的文件描述符,但它起源于系统V,所以poll与STREAMS系统紧紧相关。
4,poll和select函数在被信号中断后都不会被重启动,即使启用了SA_RESTART函数。
第六节 异步I/O
1,select和poll对任意描述符都能工作。
2,在系统V派生的系统中,异步I/O只对STREAMS设备和STREAMS管道起作用。在BSD派生的系统中,异步I/O只对终端和网络起作用。
第七节 readv和writev函数
1,readv和writev函数用于在一次函数调用中读写多个非连续缓冲区。
第八节 readn和writen函数
1,readn和writen函数并非任何标准的组成部分。
2,注意read,write函数返回值小于要求值的情况。
第九节 存储映射I/O
1,存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区相映射。
2,将一个普通文件复制到另一个普通文件中时,存储映射I/O比较快。但是有一些限制,例如,不能用其在某些设备(如网络设备或终端设备)之间进行复制,并且在对被复制的文件进行映射后,也要注意该文件的长度是否改变。
第十节 小结
PS:这章在STREAMS一节纠结了好久还是没看懂,其他的也只是基本看了个概念。期间也跳到第十五章看了一下前几节。