美文网首页静心学习之路系列
静心学习之路(5)——事件处理模式:Reactor和Proact

静心学习之路(5)——事件处理模式:Reactor和Proact

作者: 游学者夏纳 | 来源:发表于2020-11-05 16:43 被阅读0次

    Reactor模式

    一种高效的同步I/O模型的实现,Reactor模式要求主线程(I/O处理单元)只监听描述符是否有事情发生,有的话就通知工作线程(逻辑单元)。除此之外不做任何实质性的工作。

    流程:(以epoll_wait为例)
    1.主线程往epoll内核事件表注册socket读就绪事件。
    2.主线程调用epoll_wait等待socket数据可读。
    3.socket有数据可读时,epoll_wait通知主线程。主线程把socket可读事件放入请求队列。
    4.睡眠在请求队列上的某个工作线程被唤醒,它从socket读取数据,并处理请求,然后往epoll内核事件表里注册socket上的写就绪事件。
    5.主线程调用epoll_wait等待socket可写。
    6.socket可写时,epoll_wait通知主线程。主线程把socket可写事件放入请求队列
    7.睡眠在请求队列上的某个工作线程被唤醒,它在socket上写入处理的结果

    上述的流程里,工作线程从请求队列取出事件以后,根据类型做对应的处理,对与可读事件做读数据和处理的操作;对于可写事件执行写的操作,因此不区分所谓的读工作线程和写工作线程

    Proactor模式

    一种高效的异步I/O模型的实现,Proactor模型将所有的I/O操作都交给主线程和内核来处理,工作线程只负责业务逻辑。

    流程:(以aio_read和aio_write为例)
    1.主线程调用aio_read函数,向内核注册socket上的读完成事件,并告诉内核缓冲区的位置,以及操作完成时如何通知应用程序(比如信号)。
    2.主线程继续处理其他逻辑。
    3.socket上的数据被读入用户缓冲区以后,内核向应用程序发送一个信号,通知数据已可用。
    4.应用程序通过回调,选择一个工作程序来处理客户请求。工作线程处理完之后,调用aio_write函数调用向内核注册socket上的写完成事件,并告诉内核缓冲区的位置,以及操作完成时如何通知应用程序(比如信号)。
    5.主线程继续处理其他逻辑。
    6.当用户缓冲区的数据被写入socket之后,内核向应用程序发送一个信号,通知应用程序数据发送完毕。
    7.应用程序通过回调,选择一个工作线程做善后处理,比如关闭socket。

    例子中socket上的读写事件是通过aio_read和aio_write注册到内核的,因此内核可以通过信号报告给应用程序socket上的读写事件。所以当主线程调用epoll_wait时仅能用来检测监听socket上的连接请求事件,而不能用来检测socket上的读写事件。

    补充:模拟Proactor模式

    一种用同步IO模拟Proactor的方法,主线程执行数据读写,完成之后向工作线程通知这一“完成事件”。那么工作线程就直接获得了数据读写的结果,接下来对结果逻辑处理即可。

    流程:(以epoll_wait为例)
    1.主线程往epoll内核事件表注册socket读就绪事件。
    2.主线程调用epoll_wait等待socket数据可读。
    3.socket有数据可读时,epoll_wait通知主线程。主线程把从socket循环读取数据,直到没有数据可读,然后把读取到的数据封装成一个请求对象并插入请求队列。
    4.睡眠在请求队列上的某个工作线程被唤醒,它获得请求对象并处理请求,然后往epoll内核事件表里注册socket上的写就绪事件。
    5.主线程调用epoll_wait等待socket可写。
    6.socket可写时,epoll_wait通知主线程。主线程把socket可写事件放入请求队列
    7.睡眠在请求队列上的某个工作线程被唤醒,它在socket上写入处理的结果

    (之后的总结不一定按模块来,觉得自己哪里欠缺就先看哪里)

    相关文章

      网友评论

        本文标题:静心学习之路(5)——事件处理模式:Reactor和Proact

        本文链接:https://www.haomeiwen.com/subject/nchnvktx.html