linux将所有外部设备都看做一个文件来进行操作。因此,linux对所有外部设备的操作都可以看做是文件的操作。文件的操作当然需要有个标示描述它,这就是文件描述符(file descriptor)。
我们说网络socket的read()是一个io操作命令,具体流程是这样的:
应用程序调用read命令,通知内核需要做读取数据操作
内核创建一个文件描述符
内核从物理层收到读数据的命令,从网络中获取数据包
数据包传递到tcp/ip层,解析数据包的头
内核将数据包缓存在文件描述符的读缓存区(接受缓存区)中,注意这里的读缓存区是在内核中的
当文件描述符读缓存区数据字节数大于应用程序定义的低水位的时候(read的一个参数),此时文件描述符处于读就绪的状态
将读缓存区中的数据复制到应用程序(用户区)返回

这里需要说明的是
1 每个文件描述符都有自己的读缓冲区和写缓冲区,读缓冲区对应的是read操作,写缓冲区对应的就是write操作了
2 读缓冲区和写缓冲区都是在内核区中
现有的linux io模型有5种:
阻塞式io模型,非阻塞式io模型,io复用模型,信号驱动式io模型,异步io模型
经常弄不清楚的就是阻塞,非阻塞,异步,同步
说明一下
上图给出的同步异步标准是:数据描述符缓存是由谁来进行读取的?由用户程序读取,则判断为同步;由内核推送,判断为异步
上图给出的阻塞非阻塞标准是:调用的用户进程是否是阻塞的状态
这里关于这五种io模型的阻塞同步状态有很多种说法,比较有争议的是io复用模型和信号驱动io模型的判断分类上,推荐这一种判断:
<a href="http://www.360doc.com/content/12/0426/15/507289_206688978.shtml">关于io的同步、异步、阻塞、非阻塞</a>