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

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

 

 

 

 

 

keydown(fn) -JQuery API keypress(fn)-JQuery API keyup(fn)-JQuery API load(fn)-JQuery API mousedown(fn)-JQuery API mousemove(fn)-JQuery API mouseout(fn)-JQuery API mouseover(fn)-JQuery API mouseup(fn)-JQuery API one(type,data,fn)-JQuery API ready(fn)-JQuery API resize(fn)-JQuery API scroll(fn)-JQuery API select(fn)-JQuery API select()-JQuery API submit(fn)-JQuery API submit()-JQuery API toggle(even,odd)-JQuery API trigger(type)-JQuery API unbind(type,fn)-JQuery API unload(fn)-JQuery API Effects特效-JQuery API animate-JQuery API fadeIn(speed, callback)-JQuery API fadeOut(speed,callback)-JQuery API fadeTo(speed,opacity,callback)-JQuery API hide(speed,callback)-JQuery API hide()-JQuery API show(speed,callback)-JQuery API show()-JQuery API slideDown(speed,callback)-JQuery API ADO的臭虫、问题太多,只好用BDE了 kylix3装在RedHat7.3上界面显示不出来?高手请帮忙! 键盘"DEL"键和右键"删除"的区别? 打不开WORD文件? WIN98只能进安全模式,不能正常进入,什么原因 关于insertrow后不update而先getitemstring的问题。 tomcat 配置问题 C# 基于套接字的聊天室 遇到一个问题 高分请教!!! WIN95的序列号给一个谢了,各位兄弟,帮个忙。。 请问数据流程是指那方面的? 关于如何调用Windows Media Encoder 如何用vb实现将数据写入到excel和word中。请附源代码! 卖书拉,都是比较经典的,需要的看看巴 关于拨号连接的问题? 菜鸟问题:请问怎么安装Gcc3.0呀!随便问一下哪里有最新的版本下载? 关于存储过程的一些小心得(不知道对不对) 高手求救,ISAPI调用SQLserver的问题。在线等待! c语言编程访问大硬盘的物理扇区时坏扇区如何判断,如何跳过! WIN98+IE5和WIN2000+IE6运行JAVASCRIPT脚本的结果怎么不一样? 如何在只允许输入数字的文本框限制汉字的输入 求助!sql server 种子 自动标识 递增 在delphi中突然不可用??:(,嘴气歪了 出事了,我的线程停不了了。高人帮帮手。 asp连接oracle???急!!在线等待!! MSFlexGrid控件要如何添加内容? 我在基于FORMVIEW内加一个贴图的按纽,能显示,但返回时,按纽没了,且按纽地方一块灰色,为什么 如何給N條紀錄自動生成一個編號並寫入數据庫? 关于控件SmartMenuXP开发的文档 求助:混淆器JOC相关问题!!!急急急急急急急急急!!! 串口通讯 DBListBox可以直接显示出数据吗,象DBGrid一样 ** AddressOf在多线程方面后面的方法不能带参数嘛?100分送上! 急...区分两个不同按钮事件. 怎样使用SQLClientDataSet向数据库中添加和删除记录呀? 给我点勇气继续下去 在jsp中如何判断传来的字符串是8859-1编码还是gb2312编码方式 ----------m_ctrl[MAX].Create控件用DestoryWindow后怎么判断被Destory了this Help:about IIS 求Visual Studio.Net序列号!郁闷半天了! 怎么可以离开这个界面呢,在unix中 怎样在一个多线程程序中使用ADO2.7?? 域用户登录不了域…… 怎样制作VC的数据库表格?? Help:about IIS 做一消息问题? VB6和ACCESS的问题 有关Excel的简单问题 请问创建CListCtrl问题, 关于JAVA 的输入问题 请教 session 如果實現網頁的滾動信息?如果在用戶不篩新網頁的情況下更新其最新消息! 请问发布 .net WEB服务 和 WEB应用程序,需要购买哪些许可? 中国人民银行领导人指出,我国已开始实行以市场供求为基础、参考一揽子货币进行调节、有管理的浮动汇率制度.这是中国完善人民币汇率形成机制改革的一项重要举措.汇改的实施对国际贸 陈涉世家,是写陈涉的.为什么要在开头的时候介绍吴广的表字和姓名呢? = 急用,就是大概怎样 运用是什么,为什么怎么做和法律 依据之类的有没有例题无所谓,不过最好有, 经济生活 . 在超市看到水养植物玻璃瓶扣托着一个口径跟瓶口差不多大的塑料的,防止植物太小滑落,这个塑料的是什么? 我国实施的法律是怎样产生的 什么是力的示意图与图示? 题目是”陈涉世家”为何开头要并举吴广的籍贯? 政治题目 从法律角度评价其行为并指出实质 说明什么道理,启示 说明王某开车到某地去办事,倒车时不小心撞伤魏某,致其严重受伤,王某开车出逃,魏某不久后死亡,王某被判刑罚款 谷地地形对气候有什么影响 玻璃瓶里养什么植物瓶身大概十八厘米 瓶口大概四厘米的直径 单选英语 谷地地形形成的原因是什么? 玻璃瓶里能种多肉植物吗 单选,英语 问地貌是什么,答谷地和峡谷都可以么?地貌一般答什么? 火炬花可以用玻璃瓶水养吗 青藏高原对季风的影响是加剧了季风的效果还是削弱了这种效果?原因是什么呢?3楼的朋友结论应该是对的,但是我想知道具体的原因5楼回答得很具体,可是没有我想要的东西。。。6楼的同 衣藻 草履虫 酵母菌 细菌是通过什么与环境进行物质交换的 法的特征主要表现在哪里?【急用】这是一道多选题法的特征主要表现在( )A.具有国家意志的属性 B.具有国家强制性C.规定人们的权利和义务 D.是明确的、普遍的规范 云石胶能粘玻璃吗想做个玻璃架,手边有云石胶(大力胶),问能粘玻璃吗,能承受较大力度吗? 维C和海鲜能形成砒霜样的物质吗?虾和维c 蟹和维C有没得区别?砒霜的形成还需要参于哪些东西? 芦苇花象征什么 硝酸根离子和硫酸根离子是不是有氧化性呢? 为什么 谢谢了如题 谢谢了 国际联盟成立? 谷地的温度是高还是低 法律最本质的属性和最重要的特征是什么?为什么? 分析美国建立国际联盟的各种目的 中国的东北三省中的三江平原、松嫩平原、辽河平原,黑钙土分布在哪个平原的?问题如上面所述! 法律是特殊的行为规范,其特殊性表现在:()、()、().其中最重要的特征是(). 憾换偏旁写新字在组词(要同音字) 黑龙江省最大的平原是三江平原还是松嫩平原? C(H+)相同的盐酸硫酸中和碱的能力哪个强 最早提出设立国际联盟的国家是? 自来水过滤器哪个牌子好?自来水过滤器哪种好?什么牌子好? 泡在水中的植物,叶像竹子,叫什么,较常见 朋加偏旁组词怎么组词 自来水过滤器什么牌子好?家用的自来水过滤器哪种好?什么牌子好? 吃多少维生素C和虾,才会在体内生成砒霜呢? 克隆牛是转基因技术吗? 什么牌子的自来水过滤器好 我国法律是的本质是____和____的体现,是____工具法律和道德的区别:法律是由________________.道德是____________的效力高于________法律不仅具有________功能,更具有________功能 初一级政治探究与实践题(很急、、、)对待挫折,著名的数学叫华罗庚曾说过:“在科学的道路上没有平坦的大道可以走,只有一条弯曲的小径.只有不畏劳苦攀登的人,才有可能登上科学的高 生活中的病毒有哪些 初中政治中关于法律的主要内容总结 物体受力示意图的画法支持力、吸引力、拉力、摩擦力、浮力、重力……这些力的作用点该从哪画起 黑钙土和黑土有什么区别?松嫩平原和三江平原的土壤分别是哪一种呢? 浓硫酸能将木条变黑,是因为他的腐蚀性还是脱水性 克隆牛都用到什么技术简答 三江平原和松嫩平原不都是东北地区吗?为什么土壤种类不同?它们和内蒙古的土壤都是些什么种类的呢 玻璃瓶里的植物水总是会臭是怎么回事 衣藻草履虫和细菌都属于单细胞生物,它们的共同特征是都具有( )( ) 芦苇有什么作用! 蚯蚓对水的反应在一个脸盆里放入泥土和蚯蚓,在倒一些水(注意:只要浸没一半泥土就可以了)此时会有什么现象出现?在往盆里倒水,直到淹没泥土表面,这时蚯蚓有什么反应? 草履虫衣藻酵母菌水蚤都是单细胞生物吗 芦苇的功效是什么 在饲养和观察蚯蚓的实验中,用沾水的棉球清擦蚯蚓的体壁的目的是a.让体表湿润,维持正常呼吸b.保持身体柔软c.保持体表湿润,有利于运动d.降温 生活探究中国特色社会主义法律体系建设为什么要以宪法为统帅? 冬眠的动物有哪些方式为什么? 自来水里出现了一条蚯蚓,应该找谁呀
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘