Linux I/O模型

Linux的内核将所有外部设备都看做文件操作

  1. 对一个文件的读写会调用内核系统命令,返回一个file description(fd)
  2. 对一个socket读写也会相应的描述符,socketfd(socket 描述符)

描述符是一个数字,指向内核中的一个结构体(文件路径,数据区等一些属性)

Unix五种I/O模型

  1. 阻塞IO模型:最常用的IO模型,缺省情况下,所有文件操作都是阻塞的,以套接字接口为例,在进程空间中recvfrom,其系统调用直到数据包到达被复制到应用进程的缓冲区中或者发生错误时才返回,在此期间一直会等待
  2. 非阻塞IO模型:recvform从应用层到内核的时候,如果该缓冲区没有数据的话,直接返回一个EWOULDBLOCK错误,一般都对非阻塞IO模型进行轮询检查这个状态,看内核是不是有数据到来
  3. IO复用模型:Linux提供select/poll/epoll,进程通过将一个或者多个fd传递给select或poll系统调用,阻塞在select操作上,select/poll会顺序扫描是否就绪,而且支持的fd数量有限,epoll使用基于事件驱动方式代替顺序扫描,因此性能更高,当有fd就绪时,立即回调函数rollback
  4. 信号驱动IO模型:首先开启信号驱动IO功能,并通过系统调用sigaction执行一个信号处理函数(此系统立即调用返回,进程继续工作,它是非阻塞的)当数据准备就绪时,就为该进程生产一个SIGIO信号,通过信号回调通知应用程序调用recvfrom来读取数据,并通知准循环函数处理数据
  5. 异步IO:告知内核启动某个动作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们,这样的模型与信号驱动模型主要区别在于:信号驱动IO由内核通知我们何时可以开始一个IO操作,异步IO模型由内核通知我们IO何时已经完成

 

IO多路复用技术

目前支持IO多路复用技术的系统调用有select,pselect,poll,epoll

epoll的重大改进

linux 内核历史上很长一段时间使用了select做轮询和网络时间通知,但是select的一些缺陷导致它的应用受到了很大程度的限制,最终linux在新的内核版本上选择了epoll来替代select,epoll和select的原理类似,为了克服select的缺点,epoll的改进如下:

  1. 支持一个进程打开的socket描述符(fd)不受限制(仅受限于操作系统的最大文件句柄数):可以用过cat /proc/sys/fs/file-max 1gb内存的机器大约10万个句柄左右
  2. IO效率不会随着FD数目的增加而线性下降:只会对活跃的socket才会主调callback函数,不会像select/poll一样扫描全部的集合而性能线性下降,但是如果所有的socket都处于活跃,那么epoll并不比select/poll效率高太多,相反如果过多使用epoll_ctl,效率可能稍微地降低
  3. 使用mmap加速内核与用户空间的消息传递:不管select/poll/epoll都需要内核把FD消息通知给用户空间,如何避免内存复制就很重要了,epool是通过内核和用户空间mmap同一块内存来实现的
  4. epoll API更简单:epoll_create,epoll_ctl,epoll_wait涉及水平触发(数据读写未完成一直通知)和边缘触发(数据读写未完成只通知一次不再通知)

 

阻塞IO模型

进程空间中调用recvfrom,其系统调用知道数据报到达且被拷贝到应用程序进程的缓冲区中或者发生错误才返回

recvfrom->返回数据  整段时间内是被阻塞的

 

非阻塞IO模型

recvfrom从应用层到内核的时候,如果该缓冲区没有数据的话,就直接返回一个EWOULDBLOCK错误,一般都对非阻塞IO模型进行轮询检查这个状态,看内核是不是有数据到来

 

IO复用模型

linux提供select/poll,进程通过将一个或多个fd传递给select或poll系统调用 ,阻塞在select

这样select或poll可以帮我们侦测许多fd是否就绪,但是select/poll是顺序扫描fd是否就绪,而支持的fd数量有限

linux还提供了一个epoll系统调用,epoll是基于事件驱动,而不是顺序扫描:当有fd就绪,立即回调函数rollback

 

信号驱动IO模型

首先开启套接口信号驱动IO功能,并通过系统调用sigaction执行一个信号处理函数(此系统函数立即返回,进程继续工作,它是非阻塞的),当数据准备就绪时,就为该进程生成一个SIGIO信号,随机可以在信号处理程序中调用recvfrom来读数据,并通知主循环函数处理数据

 

 

异步IO

告知内核某操作,并让内核操作完抽自己从内核拷贝到用户缓冲区

信号驱动区别在于:内核通知我们何时可以启动IO操作

异步操作:内核通知我们IO何时完成

 转载于:http://www.coderss.cn/?p=2632

 

 

 

你可能感兴趣的:(io)