• 设计模式-前摄器模式(Proactor)


    本周要进行boost asio库的学习,在学习之前发现最好需要先了解一下前摄器模式,这样对asio库的理解很有帮助,故写下此文

    我之前写的随笔XShell的模拟实现中的链接方式可以说是同步的(服务器阻塞等待链接),这样当有服务器端在等待链接的时候就浪费了大量的资源,我们可以让服务器异步等待客户端的链接,服务器在等待链接的同时可以做别的事情,等到客户端链接请求到来的时候,调用一个回调执行链接,这就很灵活。

     

    先来一段关于前摄器模式的官话:前摄器模式支持多个事件处理器的多路分离和分派,这些处理器由异步事件的完成来触发。通过集成完成事件(completion event)的多路分离和相应的事件处理器的分派,该模式简化了异步应用的开发。

    简单点说,前摄器的实现多亏了多个事件处理器将事件和处理分离开,和处理方式的分派。而这些事件处理器的的触发方式是当被异步事件(仅限完成事件)通知而出发的。把这些个东西搞在一起就是前摄器模式了。

    • 前摄器(proactor)模式

    前摄器模式主要利用操作系统的异步操作特性(如果操作系统不支持异步的话前摄器模式就。。。),简单的说,当你想到异步的时候第一反应一般就是select,poll和epoll这几个函数吧(或者是类似Qt的消息和槽函数之类的),当你的select函数捕捉到一个请求的时候,就执行一个操作(例如传输一个小视频),不过这一般都是在编写的应用程序中实现的,前摄器和这个方式不同的地方就是,它可以让别人帮他干搬砖的活,当浏览器请求一个文件,事件处理器就会把这个请求告诉操作系统,让操作系统去办,而事件处理器本身只关注操作系统发送回来的完成事件,事件处理器收到完成事件就拿操作系统搬好的砖,交给工头,任务就算完成了。下面对连接请求和文件请求两个操作进行图片详解~

    1. web服务器本身应该先开启接受连接的操作,并且把异步连接(就是说select函数你得写好并且调用吧,不然怎么接受连接请求)的操作准备好,以备客户端(这里就是浏览器啦)连接
    2. 和操作系统沟通,注册相关函数(例如回调函数之类的)
    3. 为事件分离器注册好回调函数
    4. 浏览器发送连接请求
    5. 这时候连接请求的数据实质上是由操作系统接收的(应用程序把最累的活丢给操作系统干)
    6. 事件分离器本身只关注完成事件,俨然一副小工头模样(事件分离器:操作系统你干完了叫我就行)
    7. 被事件分离器通知的接收器创建http事件处理器解析请求数据

    1. 某用户通过浏览器想要下载小视频,于是就上网下
    2. 模范劳工操作系统把请求数据放在缓冲区中        操作系统:报告老大,搬完了
    3. 事件分离器把事件完成告诉事件处理器                小工头事件分离器:操作系统你干的不错,但是你的功劳是我的了       
    4. http事件处理器解析缓冲区中保存的请求数据,发现居然有人要下小视频
    5. http事件处理器只能悲催的去文件系统中同步的读文件
    6. 但是读完的数据要放在socket连接上,往这上写又耗时又费力,能不能找个老实人帮我干呢?    http事件处理器:那个谁,操作系统你过来一下,你把这些砖搬上车
    7. 操作系统写操作完成,通知事件分离器。                     操作系统:好的老大!                操作系统:报告!砖搬完了!
    8. 事件分离器把写操作完成事件报告给http事件处理器。             事件分离器:报告总指挥,货已经全部上车。       http事件处理器:不错,任务完成,又是忙碌的一天                 (操作系统:我有句。。。。不知当讲不当讲)

    总结:和一般的异步操作不同。前摄器模式会把数据的读写这种比较耗时的动作交给操作系统去做(底层快啊),而自身只关心操作系统返回的读写完成通知,自身做一些解析就好了,这样就把事件处理和文件操作分离开了(这就是事件处理器的工作)。

    到这里, 前摄器模式就讲的差不多啦,其实我一开始也不是很懂这个模式,于是把这个尽量整理成比较好懂的方式,可能有不恰当或者理解错误的地方,希望大家能帮我指出来,我进行改正

    参考资料:http://www.kuqin.com/ace-2002-12/Part-One/Chapter-8.htm

     

  • 相关阅读:
    线性表---顺序表&链表
    C++——虚函数表——typedef指向函数的指针
    C++——继承与多态
    C++——动态内存分配new--delete
    C++——模板---函数模板---类模板
    C++——指针---指向数组的指针---指向字符串的指针--指向函数的指针--指针的指针--指针的引用
    C++——this指针
    C++——运算符的重载---以成员函数方式重载---以友元函数方式重载
    C++——友元函数--友元类——friend关键字
    Ubuntu环境下实现WireShark抓取HTTPS
  • 原文地址:https://www.cnblogs.com/lenomirei/p/7353948.html
Copyright © 2020-2023  润新知