当前网络主的设计模式共有俩中,即Reactor模式和Proactor模式。同步I/O模型(select,poll,epoll等)用来实现Reactor模式,而异步(aio_read或aio_write等)用来实现Proactor模式
1.Reactor模式
Reactor模式的基本设计思路是主线程只负责对I/O事件的监听,而不负责对I/O的读写,如果有I/O事件发生,则主线成会将该事件通知给工作线程,由工作线程来完成具体的I/O读写和逻辑处理
我们以epoll为例来具体阐述它的详细过程
(1)主线程注册监听套接字的可读事件到内核事件表(之后的注册工作由工作线程来完成)
(2)主线程调用epoll_wait等待socket上的俄数据可读
(3)当socket上有数据可读时,主线程将可读事件放到请求队列
(4)睡眠在请求队列上的线程被唤醒,它从socket上读取数据,并处理客户请求,然后往内核事件表中注册socket可写事件
(5)主线程等待事件可写
(6)当socket可写时,主线程将可写事件放到请求队列
(7)睡眠在队列上的线程被唤醒,他往socket上的写入服务器处理客户请求的结果
Reactor模式的工作流程图如下
Proactor模式
Proactor与Reactor的不同之处在于Reactor将I/O处理交由工作线程来完成,而Proactor则将I/O处理通过异步I/O操作交给主线程和内核来处理,其工作线程只用来处理业务逻辑
使用异步I/O模型(aio_read,aio_write为例)的详细步骤
(1)主线程调用aio_read来向内核注册socket上的读完成事件,并告诉内核用户读缓冲区的位置,以及操作完成时如何通知应用程序(这里以信号为例,当然我们也可以以线程回调函数的方式)
(2)主线程继续处理其他逻辑
(3)当socket上有数据被读到用户缓冲区时,内核向应用程序发送一个信号,以通知应用程序数据已经可用
(4)应用程序实现定义好的信号处理函数选择一个工作线程来处理客户请求,工作线程完成客户求情之后,调用aio_write函数来向内核注册socket上的可写事件,并告诉内核用户写缓冲区的位置,以及写操作完成时该如何通知应用程序
(5)主线程继续处理其他逻辑
(6)当用户缓冲区的数据被写到socket之后,内核将向应用程序发送一个信号,以通知应用程序数据已经发送完毕
(7)应用程序预先定义好的信号处理函数选择一个工作线程来做善后处理,比如决定是否关闭socket
其具体工作流程图如下
这里写图片描述