Read分为两步:
a.Waiting for thedata to be ready(等待数据准备)。
b.Copying thedata from the kernel to the process(将数据从内核拷贝到进程中)
Blocking I/O:
官方:
个人理解:只有I/O操作完成,才能做其他事情;
Nonblocking I/O:
官方:
个人理解:进行I/O操作,内核立即返回结果;
Multiplexing I/O:
官方:
个人理解:将一些文件描述符放入集合中进行监测,如果里面有可读或可写的描述符,就让其进行读写操作。
Signal Driven I/O:
官方:
个人理解:能够进行读写了,内核发送信号到相应的进程,让其进行读写操作。
Asynchronous I/O:
官方:异步IO这个模型是真正的异步模型,他直接调用了一个系统函数,然后等待kernel的数据准备好之后直接返回一个信号。用户进程接收到这个信号之后得到从kernel发来的数据。
个人理解:
区别对比:
调用blocking IO会一直block住对应的进程直到操作完成;
non-blocking IO在kernel还准备数据的情况下会立刻返回;
A synchronous I/O operation causes the requestingprocess to be blocked until that I/O operation completes;
An asynchronous I/O operation does not cause therequesting process to be blocked;
Reactor模式是处理并发I/O比较常见的一种模式,中心思想就是,将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上。一旦有I/O事件到来或是准备就绪(区别在于多路复用器是边沿触发还是水平触发),多路复用器返回并将相应I/O事件分发到对应的处理器中。
多路复用器:
边沿触发:如果文件描述符自上次状态改变后有新的IO活动到来,此时会触发通知。在收到一个IO事件通知后要尽可能多的执行IO操作,因为如果在一次通知中没有执行完IO那么就需要等到下一次新的IO活动到来才能获取到就绪的描述符。信号驱动式IO就属于边缘触发。
水平触发:如果文件描述符已经就绪可以非阻塞的执行IO操作了,此时会触发通知.允许在任意时刻重复检测IO的状态,没有必要每次描述符就绪后尽可能多的执行IO.select,poll就属于水平触发。
参考:http://blog.csdn.net/liuxingen/article/details/38495545
与Reactor模型相对应,Proactor最大的特点是使用异步I/O。所有的I/O操作都交由系统提供的异步I/O接口去执行。Proactor多路复用器等待异步I/O完成,并调用相应的用户处理函数。
事件触发的网络库。libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。
事件驱动(event-driven),高性能;
轻量级,专注于网络,不如ACE那么臃肿庞大;
源代码相当精炼、易读;
跨平台,支持Windows、Linux、*BSD和Mac Os;
支持多种I/O多路复用技术, epoll、poll、dev/poll、select和kqueue等;
支持I/O,定时器和信号等事件;
注册事件优先级;
Greensql:使用了定时器、事件驱动i/o。这已在另篇博文中分析了。
此项目使用Reactor模式。
主线程有一个Libevent事件分发器,主要负责新的socket连接。如果有新的连接到来,将这个socket文件描述符放入队列中,通过管道通知子线程。子线程收到通知后,从队列中取出socket文件描述符, 加入到子线程的libevent中,对改socket进行读写。
如下图可以看到网络结构:
多线程模型如下: