说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

boost在windows平台下自带超强 IOCP 的ASIO

HTML文档下载 WORD文档下载 PDF文档下载
在win32平台上,asio是基于IOCP技术实现的,我以前也用过IOCP,却没想到居然能扩展成这样,真是神奇!

boost基本上啥都有,用不着用某人写的不完整的,缺陷的代码。

  ASIO攻破

  花了足足3天时间,外加1天心情休整,终于在第5天编写出了一个能运行的基于asio和thread_group的框架,差点没气晕过去,把源码都看懂了才感觉会用了。
测试了一下,debug下一万次回应耗时800+毫秒,release下是200+毫秒,机器配置双核2.5G英特尔,4个线程并行工作,无错的感觉真好,再也不用担心iocp出一些奇怪的问题啦,因为是巨人们写的实现,呵呵。

  进入正题,简要说一下asio的实现原理吧。在win32平台上,asio是基于IOCP技术实现的,我以前也用过IOCP,却没想到居然能扩展成这样,真是神奇!在其他平台下还会有别的方法去实现,具体见io_service类下面这部分的源码:

 

// The type of the platform-specific implementation.#if defined(BOOST_ASIO_HAS_IOCP)   typedef detail::win_iocp_io_service impl_type;   friend class detail::win_iocp_overlapped_ptr;#elif defined(BOOST_ASIO_HAS_EPOLL)   typedef detail::task_io_service<detail::epoll_reactor<false>> impl_type;#elif defined(BOOST_ASIO_HAS_KQUEUE)   typedef detail::task_io_service<detail::kqueue_reactor<false>> impl_type;#elif defined(BOOST_ASIO_HAS_DEV_POLL)   typedef detail::task_io_service<detail::dev_poll_reactor<false>> impl_type;#else   typedef detail::task_io_service<detail::select_reactor<false>> impl_type;#endif

这部分代码其实就在boost::asio::io_service类声明中的最前面几行,可以看见在不同平台下,io_service类的实现将会不同。很显然,windows平台下当然是win_iocp_io_service类为实现了(不过我一开始还以为win_iocp_io_service是直接拿出来用的呢,还在疑惑这样怎么有移植性呢?官方文档也对该类只字不提,其实我卡壳就是卡在这里了,差点就直接用这个类了^_^!)。

  那么就分析一下win_iocp_io_service的代码吧,这里完全是用IOCP来路由各种任务,大家使用post来委托任务,内部调用的其实是IOCP的PostQueuedCompletionStatus函数,然后线程们用run来接受任务,内部其实是阻塞在IOCP的GetQueuedCompletionStatus函数上,一旦有了任务就立即返回,执行完后再一个循环,继续阻塞在这里等待下一个任务的到来,这种设计思想堪称神奇,对线程、服务以及任务完全解耦,灵活度达到了如此高度,不愧为boost库的东西!我只能有拜的份了...


  说一下总体的设计思想,其实io_service就像是劳工中介所,而一个线程就是一个劳工,而调用post的模块相当于富人们,他们去中介所委托任务,而劳工们就听候中介所的调遣去执行这些任务,任务的内容就写在富人们给你的handler上,也就是函数指针,指针指向具体实现就是任务的实质内容。其实在整个过程中,富人们都不知道是哪个劳工帮他们做的工作,只知道是中介所负责完成这些就可以了。这使得逻辑上的耦合降到了最低。不过这样的比喻也有个不恰当的地方,如果硬要这样比喻的话,我只能说:其实劳工里面也有很多富人的^o^! 。很多劳工在完成任务的过程中自己也托给中介所一些任务,然后这些任务很可能还是自己去完成。这也难怪,运行代码的总是这些线程,那么调用post的肯定也会有这些线程了,不过不管怎么说,如此循环往复可以解决问题就行,比喻不见得就得恰当,任何事物之间都不可能完全相同,只要能阐述思想就行。


  最后还要说明的一点就是:委托的任务其实可以设定执行的时间的,很不错的设定,内部实现则是通过定时器原理,GetQueuedCompletionStatus有一个等待时间的参数似乎被用在这方面,还有源码中的定时器线程我并没有过多的去理解,总之大体原理已基本掌握,剩下的就是使劲的用它了!!!


  另外为了方便人交流,在这里插入一些代码可能更容易让人理解吧,
  下面这个是启动服务时的代码:

 

void ServerFramework::run(){     boost::thread_group workers;    for (uint32 i = 0; i < mWorkerCount; ++i)         workers.create_thread(             boost::bind(&boost::asio::io_service::run, &mIoService));     workers.join_all();}

在打开前就得分配好任务,否则线程们运行起来就退出了,阻塞不住,任务的分配就交给open函数了,它是分配了监听端口的任务,一旦有了连接就会抛出一个任务,其中一个线程就会开始行动啦。

 

void ServerFramework::open(const String& address, const String& port, uint32 nWorkers /**//*= DEFAULT_WORKER_COUNT*/){    // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).     boost::asio::ip::tcp::resolver resolver(mIoService);     boost::asio::ip::tcp::resolver::query query(address, port);     boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);      mAcceptor.open(endpoint.protocol());     mAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));     mAcceptor.bind(endpoint);     mAcceptor.listen();      mNextConnection = new Connection(this);     mAcceptor.async_accept(mNextConnection->getSocket(),         boost::bind(&ServerFramework::__onConnect, this,         boost::asio::placeholders::error));      mWorkerCount = nWorkers;    if (mWorkerCount == DEFAULT_WORKER_COUNT)    {         mWorkerCount = 4;     }}

open函数中给io_service的一个任务就是在有链接访问服务器端口的情况下执行ServerFramework::__onConnect函数,有一点需要格外注意的,io_service必须时刻都有任务存在,否则线程io_service::run函数将返回,于是线程都会结束并销毁,程序将退出,所以,你必须保证无论何时都有任务存在,这样线程们即使空闲了也还是会继续等待,不会销毁。所以,我在ServerFramework::__onConnect函数中又一次给了io_service相同的任务,即:继续监听端口,有链接了还是调用ServerFramework::__onConnect函数。如果你在ServerFramework::__onConnect执行完了还没有给io_service任务的话,那么一切都晚了...... 代码如下:

 

void ServerFramework::__onConnect(const BoostSysErr& e){    if (e)    {         MOELOG_DETAIL_WARN(e.message().c_str());     }      Connection* p = mNextConnection;     mNextConnection = new Connection(this);     // 再次进入监听状态     mAcceptor.async_accept(mNextConnection->getSocket(),         boost::bind(&ServerFramework::__onConnect, this,         boost::asio::placeholders::error));     // 处理当前链接     __addConnection(p);     p->start();}

最后,展示一下这个类的所有成员变量吧:

 

 // 用于线程池异步处理的核心对象    boost::asio::io_service mIoService;    // 网络链接的接收器,用于接收请求进入的链接    boost::asio::ip::tcp::acceptor mAcceptor;    // 指向下一个将要被使用的链接对象    Connection* mNextConnection;    // 存储服务器链接对象的容器    ConnectionSet mConnections;    //// 为链接对象容器准备的strand,防止并行调用mConnections    //boost::asio::io_service::strand mStrand_mConnections;    // 为链接对象容器准备的同步锁,防止并行调用mConnections    boost::mutex mMutex4ConnSet;    // 为控制台输出流准备的strand,防止并行调用std::cout    AsioService::strand mStrand_ConsoleIostream;    // 工作线程的数量    uint32 mWorkerCount;

但愿这篇随笔也能对正在研究asio的朋友们有所帮助吧。

转载自:http://www.cppblog.com/shanoa/archive/2009/06/26/88606.aspx

 

 

 

 

 

BYOD浪潮即将来袭 六大年轻杀手重塑企业软件 灵活运用AppFlood:提高APP eCPM的10个技巧 事半功倍:你应该知道的HTML5五大特性 创建API监视器的五大技巧 流量激增15倍+ 乐蜂网桃花节大促背后的技术事 Windows 8和IE 10:如何保障视频播放? 云计算大会讲师秀之13:梁家恩,12年积累,构建永久免费的语音云平台 众望所归:智能手机芯片将为服务器所用 没有学位,他通过以下四步进入Google 谈谈Google Polymer以及Web UI框架的未来 保密入髓:前苹果员工揭示公司是如此善于保守秘密 调查显示:软件开发公司出现“人才荒” 三星拟6月20日在伦敦召开新品发布会 推手机新品Galaxy和ATIV 历届中国云计算大会PPT集萃(五):数据安全隐患解析与应对 搞趣网创始人:做不了阳春白雪 就做下里巴人 CMDN Club 28期:创业公司一定不要浪费资源 浅谈Lean UX:我们到底该怎么设计? 张艺谋今日正式加盟乐视 作品专区落户超级电视 WebKit华丽转身:欧朋浏览器8.0新鲜出炉 分析师称应出售Bing?除非微软倒闭,否则不可能卖Bing Go Mobile沙龙第二期:软硬整合与创客精神 专访西电黄宝林:《基于GPU的并行NMF网络聚类算法》获奖背后故事 友友姚宏宇:用C,C++和Java实现自主研发之后,放开心态迎“高朋” 新技术对传统学科的颠覆:系谱网使用大数据寻亲问祖 IDC:2015年全球平板电脑出货量将超PC Web开发者的福利 30段超实用CSS代码 库克出席D11科技大会:苹果公司没有陷入麻烦 千兆的带宽是不够的,最新研究将我们带入400G时代! 告诉你一个事实:移动互联网依然不大 一切才刚刚开始 戴尔的10亿美元云扩建计划到底是什么? iOS vs. Android,应用设计该如何对症下药? 有关DBHCP 求救,谁有pb6.5的光盘。想买一张或者刻一张(限北京) 请教:jdbc 连线管理 高手们,怎么动态生成button??? 好消息!!! 购买外文原版书的朋友---》www.china-pub.com 如何制作包含系统驱动程序的安装盘? 为什么会发出这样的声音? 从98年到2000年中程水平考试上午题就没高过45分,这次上午题普遍认为比前几年难,该不会超过45分把。 ————————————简单的问题 怎样将AutoCAD图形存储到SQL SERVER中,而且不是存路径 请问怎么样知道当前记录属于表中的第几条记录(我用的是ADODC控件) ????请问怎么在Applet应用程序中打开Word文档?????? #####救我啊~~~~~文件好好的为什么坏了###### 我已被richeditctrl折腾得不行了,我有些文本要显示,只要求能改变颜色,行距,能该字体最好,谁能给我推荐一个控件,我备有厚礼! 一个C问题! 急!!!!高手请赐教! 请问我有一张FAT32的软盘,能不能在linux下读取盘上的内容呢? 关于连接共享的问题, 请帮忙 如何对动态创建地组件进行操作???救命!!!!! 请问嵌入式开发和单片机方面有什么关系??? WTO向中国开出首张罚单! 请问各位大侠,在西安哪里有介绍db2的书的? 我以前用VB,现在想转向VC++,可我看了一些VC++的入门书根本摸不着头脑,各位老师,我该如何是好??? 谁用过TextRect这个过程,为什么它的最后一个参数TextFlags无法用,一加上这个参数就报告参数个数太多? 请教一个关于Session的问题 急用,一个票据打印的问题???请教各位高手!多谢! 请哪位大虾解释一下线程中语句sleep(n)的含义,谢谢!!!! Norwaywoods(挪威的森林),谢谢你,请来拿分呀,天,送分都这么难!!! boundschecker大讨论,为何运行vc的go完毕后,未报内存泄露,但boundschecker去却报了一大堆错,信谁?详见内 关于java中,ftp的问题,用FtpClient如何获取server端的目录结构啊,多谢。 任务管理器不能正常工作 〉〉〉〉如何才能使用户禁止修改表单上的某些域??? 请问如何使某个窗体总是最上面,而且总是当前活动窗口? 如何保存对OLE对象(位图)的修改?在关闭OLE调用之后 '如何在ActiveReport1.0中的得知报表中当前打印位置. 请问考过MCSD的大虾,MCSD考试的题目是中文还是英文,每一门是多少钱? !!怎么让运行程序后的图标显示在任务栏中,即和输入法的图标放在一起 insmod ***.o 提示设备或资源忙!什么问题?????? 请教高手! 我以前没做过lotus开发,想转做这个不知该从何入手,请各位前辈指教(是不是如果没有项目经验找工就特别难?) 请问如何改变datagrid、sstab的颜色? 急!!! 请海星看过来,有关The art of computer programming 请教高手!很急的哦 java怎么处理无限循环中不可到达的语句?请指教,谢谢 asp的登录的验证漏洞如何解决 那里有文明3的下载呀? ORACL8的问题,进来看看 有谁知道现在北京有卖<寻秦记>后20集的吗? 请问哪里能下载到ASP电子商务的程序?谢谢! 标准c中有没有判断在某个目录下某种类型的文件是否存在的函数?比如e:\debug\*data*.ard 高一物理第六题 有一只“12V,6W”的电灯泡和一个15V的电源,要使灯泡正常发光,需要将电灯泡和一个电阻串联在电路中,1)这只电阻的阻值多大2)这个电路消耗总功率多大 电解盐水的黄色液体我用镍制电极电解盐水,负极有大量氢气产生,正极却什么也没,过一段时间,水变成深黄色,是什么?可它不是气体呀,可我把水倒在铬片上,生锈了这么强的氧化性很像是氯. 甲乙两个工程队合修一条路,甲队的工作效率是乙队的3/5 .两队合修6天正好完成这条路的2/3,余下的由乙队单独各位好心的网友们 我脑子 有点 转不过弯来 写的时候 这一步 求出来的 是什么! 有一辆汽车以匀速340米每秒的速度走了100米,求行驶了100米时间.莪算的是340/100,但是莪得出来的是3.4,34,但是不知道落下了什么. 知道刹车距离如何计算出多少车速机动车:6.2米货车(空车自重4.2),8.25-16双钱轮胎.刹车距离:22.5米(空车).请问当时按计算是多少车速. 三元乙丙橡胶的日常用途日常生活中有哪些物品能用到三元乙丙橡胶,河北省有做这个的厂家吗?我想弄点样品做实验,用在汽车轮胎上 一辆列车过一架长100米的桥用了20秒,过一架200米的桥用了30秒,他与一辆200米的速度是每秒20米的列车错车用多少时间不用二元一次方程怎么解 矿泉水滴下什么东西起化学反应成黄色? 谁知道525型三元乙丙橡胶的性能参数和用途. 甲,乙两个工程队合作一项工程,需16天完成,现两个队合作9天后,甲对被调走,乙对又单独做啦21天完成,若甲队单独做需要x天完成,则可列出的方程式为 急,如何根据刹车距离计算车速黑色老式皇冠,刹车距离8米,晴天,普通城市公路,请教各位大侠当时车速多少?十万火急!亲人遇交通事故,交警只告知了刹车距离,就想问问看能不能根据刹车距离算 杀虫剂喷完以后需要清理喷过的地方吗?它自己会挥发干净吗? 汽车上桥时,速度会变慢,为什么?是因为功率不变,做的功变大, 刹车距离如何计算? 是不是每种杀虫剂的挥发时间都相同 水质电解器其实是真的可以鉴定水质?我特别考虑了一下发现,电解后有可能是真的!因为氯化铁(绿)、十二水合硫酸铝钾(蓝)、三氧化二铁(黄)原理其实是用铁与矿物质发生化学反应生 知道刹车距离如何计算车速?车是牡丹客车MD6800C、路面是的沥青路面.刹车距离为左轮22.8米,右轮25.4米.它的车速是多少?是否为偏刹? 杀虫剂多久可以挥发 氧化铜制铜的化学方程式 标有“6V 6W”,“9V 3W”字样的灯L1和L2串联在某电源上,设灯丝的电阻不变,0 - 离问题结束还有 14 天 16 小时要保证两灯安全工作,电源电压不应超过多少伏?若将两灯并联使用,要保证两灯安全工 油基杀虫剂会挥发吗我不懂这个结果喷了很多在房间内 而且散了很久都是烟雾缭绕 我就睡觉了没什么问题吧而且地板 电脑...满屋子都是油 该怎么办?收拾的话很费劲 放置的话那层油那挥发 铜粉和空气反应,制得氮气的化学方程式 晶体和非晶体在凝固和溶化相同点刚才看个卷子上的题说晶体和非晶体在凝固和溶化过程中相同点是什么?答案上写的是必须吸热,我知道,溶化吸热,凝固放热.不知道凝固怎么吸热了? 雷达杀虫剂多久挥发完 用铝丝和硫酸铜溶液制“铜树”的化学反应方程式 晶体和非晶体的凝固的特点和条件 如图所示的电路中,定值电阻R的阻值为36欧,闭合开关后电压表示数为2.4伏,灯泡L的电阻为12欧,求通过灯泡L的电流,电源电压U和定值电阻R的电功率. 求高中有关于铜的所有化学反应方程式.有关铜的. 非晶体的融化或凝固条件是什么 如图a所示电路中,已知固定电阻R=24欧,电源电压U=10V,电阻R0=1欧,灯泡L的I-U图像如图b所示,电键K闭合后电路中电流强度为?此时灯泡电阻为? 硝酸铜和一种常见廉价金属反应制铜的化学方程式 非晶体融化,凝固规律. 怎么算摩擦系数 一个灯泡正常发光电压是12V,现串联在一个电源电压20V的电路中,应安一个多大的电阻 晶体凝固后是(晶体还是非晶体?)请说出理由 将该电路图中的灯泡换成五欧,十欧,十五欧,二十欧,二十五欧的定值电阻,滑动变阻器接入电路阻值为14欧,图丁为接入电路的定值电阻的电阻与电流关系问所选的定值电阻阻值为多少 某项工程由甲乙两个工程队合作4天后,因甲有其它任务,由乙工程队再单独做五天才完成,如果单独完成这项工作甲比乙工程队少用五天,求甲乙单独完成这项工作各需几天 甲,乙两队合作一项工程,甲的工作效率是乙的1.5倍,如果甲队先做5天后,乙队赶来乙单独做各需要多少天才能完成这项工程?要设X列方程甲,乙两队合作一项工程,甲的工作效率是乙的1.5倍,如果甲 盛放化学药品的瓶子叫什么如题~比如盛放硝酸的那种瓶子~ 如右图所示电路,电源两端电压为20V不变,用滑动变阻器调节灯泡两端的电压.已知灯泡电阻为5Ω不变,滑动阻器的最大电阻为20Ω.当滑动变阻器的滑片从a端移到b端的过程中,灯泡两端的电压变化 请问电解水与纯水机(有RO膜的那种)+矿化滤芯过滤出来的水哪个更适合人们饮用? 为什么化学药品常装在棕色的瓶里? 一件工程,甲乙合做30天完成,甲乙合作9天后,由乙独做用了28天才完成,如果甲,乙单独完成各需多少天?(要有过程,)0(^-^)0 净水机过滤出来的水,可以直接喝吗? 为什么化学药品有的要装在棕色瓶子里? 那个棕色的瓶子里装的是什么?我今天看到几个年轻人在抢一个棕色的瓶子,他们称呼那个叫手榴弹~大概是因为瓶子的外形像,上大学的时候看有男同学也拿过这种东西,这瓶子里装的是什么?听 水被电解后出现有黄绿色东西(能溶解于水),这个能溶于水的东西是什么?我在家做电解水的实验 但是水中出现了有黄绿色东西(能溶解于水),这个能溶于水的东西是什么? 高一物理 第六题 在图13所示的电路中,已知电源电压U=15V,灯泡L规格为“12V 6W”,电阻R2=60欧,滑动变阻器R1的最大阻值为40欧,开关S闭合后(1)当开关S1、S2都断开时,灯泡L刚好正常发光,R1接入电路中的电阻值多大? 水能被电解,还有其它方法分解水吗? 为什么见光易分解的化学药品要放在棕色的瓶子里?别的带颜色的不行吗? 一只标有12V 6W 的灯泡,为了使他能在24V的电路中正常发光,必须给它__连一个__欧的电阻此时电阻消耗的公 若将一盏标有"6V,3W"字样的小灯泡接入9V的电源,要使小灯泡正常工作,应____联一个_____欧姆的电阻. 3.设想在月球表面上,宇航员测出小物体自由下落h高度所用的时间为t,当飞船在靠近月球表面圆轨道上飞行时,测得其环绕周期是T,已知引力常量为G,根据上述各量,试求:(1)月球表面的重力加速度 把一个标有“6V,6W”的小灯泡连接在15V的电路中,且要求正常发光,那么需 连一个阻值为 Ω的电阻 今有"6V,3W"的灯泡一只,9V电源一个,要使小灯泡正常发光,(1)必须串联多大的电阻?电阻消耗的电功率多大? 为什么有些化学药品用棕色瓶子装? 标有"6V 3W"灯泡接入19伏电路中,要正常发光,必须_联一个阻值为_欧的电阻,该电阻在灯泡正常发光时消耗的功率为_瓦 成桶的矿泉水能做铅酸蓄电池的电解液吗?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn