当前位置:首页 > 芯闻号 > 充电吧
[导读]你应该已经发现大部分使用Boost.Asio编写的代码都会使用几个io_service的实例。io_service是这个库里面最重要的类;它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异

你应该已经发现大部分使用Boost.Asio编写的代码都会使用几个io_service的实例。io_service是这个库里面最重要的类;它负责和操作系统打交道,等待所有异步操作的结束,然后为每一个异步操作调用其完成处理程序。
       如果你选择用同步的方式来创建你的应用,你则不需要考虑我将在这一节向你展示的东西。 你有多种不同的方式来使用io_service。在下面的例子中,我们有3个异步操作,2个socket连接操作和一个计时器等待操作:
1.单线程:一个io_service实例和一个处理线程

io_service service; // 所有socket操作都由service来处理
ip::tcp::socket sock1(service);
ip::tcp::socket sock2(service);
sock1.async_connect( ep, connect_handler);
sock2.async_connect( ep, connect_handler);
deadline_timer t(service, boost::posixtime::seconds(5));
t.async_wait(timeout_handler);
service.run();

2.多线程:一个io_server实例和多个处理线程

io_service service;
ip::tcp::socket sock1(service);
ip::tcp::socket sock2(service);
sock1.async_connect( ep, connect_handler);
sock2.async_connect( ep, connect_handler);
deadline_timer t(service, boost::posixtime::seconds(5));
t.async_wait(timeout_handler);
for ( int i = 0; i < 2; ++i)
    boost::thread(run_service);
void run_service()
{
    service.run();
}

3.多线程:多个io_service实例和多个线程

io_service service[2];
ip::tcp::socket sock1(service[0]);
ip::tcp::socket sock2(service[1]);
sock1.async_connect( ep, connect_handler);
sock2.async_connect( ep, connect_handler);
deadline_timer t(service[0], boost::posixtime::seconds(5));
t.async_wait(timeout_handler);
for ( int i = 0; i < 2; ++i)
    boost::thread( boost::bind(run_service, i));
void run_service(int idx)
{
    service[idx].run();
}

       首先,要注意你不能拥有多个io_service实例却只有一个线程。下面的代码片段没有任何意义:

for ( int i = 0; i < 2; ++i)
    service[i].run();

       上面的代码片段没有意义是因为service[1].run()需要service[0].run()先结束。因此,所有由service[1]处理的异步操作都需要等待,这显然不是一个好主意。
       在前面的3个方案中,我们在等待3个异步操作结束。为了解释它们之间的不同点,我们假设:过一会操作1完成,然后接着操作2完成。同时我们假设每一个完成处理程序需要1秒钟来完成执行。
       在第一个例子中,我们在一个线程中等待三个操作全部完成,第1个操作一完成,我们就调用它的完成处理程序。尽管操作2紧接着完成了,但是操作2的完成处理程序需要在1秒钟后,也就是操作1的完成处理程序完成时才会被调用。
       在第二个例子中,我们在两个线程中等待3个异步操作结束。当操作1完成时,我们在第1个线程中调用它的完成处理程序。当操作2完成时,我们立即在第2个线程中调用它的完成处理程序(当线程1在忙着响应操作1的处理程序时,线程2可以自由处理任何新进来的操作)。
       在第三个例子中,因为操作1是sock1的connect,操作2是sock2的connect,所以应用程序会表现得像第二个例子一样。线程1会处理sock1 connect操作的完成处理程序,线程2会处理sock2 connect操作的完成处理程序。然而,如果sock1的connect操作是操作1,deadline_timer t的超时操作是操作2,线程1将最终处理sock1 connect操作的完成处理程序。因此,deadline_timer t的超时操作必须等sock1 connect操作的完成处理程序结束(等待1秒钟),因为线程1要顺序处理sock1的连接处理程序和t的超时处理程序。
下面是你需要从前面的例子中学到的:
1.方案一适合非常基础的应用。因为是串行的方式,所以当几个处理程序需要被同时调用时,你通常会遇到瓶颈。如果一个处理程序需要花费很长的时间来执行,所有随后的处理程序都不得不等待。
2.方案二适合大多数应用。他是非常健壮的——如果几个处理程序被同时调用了(这是有可能的),它们会在各自的线程里面被调用。唯一的瓶颈就是所有的处理线程都很忙的同时又有新的处理程序被调用。然而,这是有快速的解决方式的,增加处理线程的数目即可。
3.方案三四最复杂也是最灵活的。你只有在第二种情况不能满足需求时才使用它。这种情况一般就是当你有成千上万并发(socket)连接时。你可以认为每一个处理线程(运行io_service::run()的线程)有它自己的select/epoll循环;它等待任意一个socket连接,然后监听一个读写操作,当它发现这种操作时,就执行。大部分情况下,你不需要担心什么,唯一你需要担心的就是当你监听的socket数目以指数级的方式增长时(超过1000个socket)。在那种情况下,有多个select/epoll循环会增加应用的响应时间。
       如果你觉得你的应用程序可能需要转换到第三种模式,请确保监听操作的这段代码(调用io_service::run()的代码)和应用程序其他部分是隔离的,这样你就可以很轻松地对其进行更改。
       最后,需要一直记住的是如果没有其他需要监控的操作,run()就会结束,就像下面的代码片段:

io_service service;
tcp::socket sock(service);
sock.async_connect( ep, connect_handler);
service.run();

       在上面的例子中,只要sock建立了一个连接,connect_handler就会被调用,然后接着service.run()就会完成执行。
       如果你想要service.run()接着执行,你需要分配更多的工作给它。这里有两个方式来完成这个目标。一种方式是在connect_handler中启动另外一个异步操作来分配更多的工作。 另一种方式会模拟一些工作给它,用下面的代码片段:

typedef boost::shared_ptr work_ptr;
work_ptr dummy_work(new io_service::work(service));

      上面的代码可以保证service.run()一直运行直到你调用service.stop()或者dummy_work.reset(0);// 销毁 dummy_work.


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭