Boost-asio之二

    上一篇介绍了Boost.Asio的一些特性,但是相对抽象和离散,这篇博客从Boost.Asio的基础知识一步步深入,读完之后对Boost.Asio会有全面的了解和掌握。Boost.Asio通过采用C++以及Boost库的语法特性,提供跨平台的异步网络IO能力。因此使用Boost.Asio需要基本的网络知识,C++、Boost知识。

        io_service是Boost.Asio的核心类,run()方法是它的重要方法之一,后续会陆续介绍到其dispatch,post,stop,reset等重要方法。run()方法的作用是阻塞程序直到所有的工作都完成,所有的handler都dispatch了;或者当调用stop方法时,run()方法也会不再阻塞下去。下面是一个说明run()方法的示例程序:

  1. #include <boost/asio.hpp>   
  2. #include <iostream>   
  3.   
  4. int main( int argc, char * argv[] )  
  5. {  
  6.     boost::asio::io_service io_service;  
  7.   
  8.     io_service.run();  
  9.   
  10.     std::cout << "Do you reckon this line displays?" << std::endl;  
  11.   
  12.     return 0;  
  13. }  
#include <boost/asio.hpp>
#include <iostream>

int main( int argc, char * argv[] )
{
	boost::asio::io_service io_service;

	io_service.run();

	std::cout << "Do you reckon this line displays?" << std::endl;

	return 0;
}
在Linux下在安装完Boost后,采用g++ 1a.cpp -o 1a -lboost_system进行编译(Boost.Asio会调用boost_system库的内容,所以需要指定链接内容,涉及到线程和多线程时,则分别要做如下指定 -pthread -lboost_thread-mt)。运行可执行文件,我们发现会有输出,这是因为没有给io_service添加任务,它自然就结束了,不会阻塞。

        通常我们不希望程序自动退出,因为可能还有其它任务需要处理,更多的时候希望控制程序何时退出,Boost.Asio考虑到了这点,看下面的例子:

  1. #include <boost/asio.hpp>   
  2. #include <iostream>   
  3.   
  4. int main( int argc, char * argv[] )  
  5. {  
  6.     boost::asio::io_service io_service;  
  7.     boost::asio::io_service::work work( io_service );  
  8.   
  9.     io_service.run();  
  10.   
  11.     std::cout << "Do you reckon this line displays?" << std::endl;  
  12.   
  13.     return 0;  
  14. }  
#include <boost/asio.hpp>
#include <iostream>

int main( int argc, char * argv[] )
{
	boost::asio::io_service io_service;
	boost::asio::io_service::work work( io_service );

	io_service.run();

	std::cout << "Do you reckon this line displays?" << std::endl;

	return 0;
}
运行上面的例子,我们发现程序没有输出也不退出,在按Ctrl+C后程序才会终止。这主要是因为我们给了io_service工作---work,它在没有完成工作的情况时是不会退出的,在io_service.run()从io_service中删除work,程序就退出了。如果不喜欢用阻塞的方法来运行事件处理,Boost.Asio也提供了其它类似BSD socket的任务调度方法,poll就是其中之一。poll调用io_service的事件循环来运行已经就绪的handler方法,下面是一个poll的示例(用for模拟程序运行的循环):

  1. #include <boost/asio.hpp>   
  2. #include <iostream>   
  3.   
  4. int main( int argc, char * argv[] )  
  5. {  
  6.     boost::asio::io_service io_service;  
  7.   
  8.     forint x = 0; x < 42; ++x )  
  9.     {  
  10.         io_service.poll();  
  11.         std::cout << "Counter: " << x << std::endl;  
  12.     }  
  13.   
  14.     return 0;  
  15. }  
#include <boost/asio.hpp>
#include <iostream>

int main( int argc, char * argv[] )
{
	boost::asio::io_service io_service;

	for( int x = 0; x < 42; ++x )
	{
		io_service.poll();
		std::cout << "Counter: " << x << std::endl;
	}

	return 0;
}

程序输出为0到41然后退出;如果这时也给io_service工作---work,而不reset,结果会是怎样呢?

  1. #include <boost/asio.hpp>   
  2. #include <iostream>   
  3.   
  4. int main( int argc, char * argv[] )  
  5. {  
  6.     boost::asio::io_service io_service;  
  7.     boost::asio::io_service::work work( io_service );  
  8.   
  9.     forint x = 0; x < 42; ++x )  
  10.     {  
  11.         io_service.poll();  
  12.         std::cout << "Counter: " << x << std::endl;  
  13.     }  
  14.   
  15.     return 0;  
  16. }  
#include <boost/asio.hpp>
#include <iostream>

int main( int argc, char * argv[] )
{
	boost::asio::io_service io_service;
	boost::asio::io_service::work work( io_service );

	for( int x = 0; x < 42; ++x )
	{
		io_service.poll();
		std::cout << "Counter: " << x << std::endl;
	}

	return 0;
}


        程序仍然输出为0到41然后退出。这是因为poll方法是非阻塞的,它只是检查当前工作队列中是否有就绪的,有就执行,然后立刻返回。在实际项目中,for循环一般是某种形式的事件循环。上面这个例子也说明了Boost.Asio的事件处理机制,work 对象给io_service对象提供工作内容,但如果在事件处理handler中再给io_service提供work,那么work将会递归无穷的产生,poll将永远不会结束。所以work的添加是在事件处理函数外部进行的。

     也就是说可以根据程序的设置,选择采用run()方法还是poll方法来运行程序。当然也有一些变体,run_one(),poll_one(),它们分别表示每次只执行一个事件处理handler,这在并发时能够很好的控制程序。

      从io_service.run()从io_service中删除work会使io_service.run()结束阻塞状态,但是io_service并没有这样的成员函数,这时必须通过智能指针来实现:通过reset智能指针来删除智能指针所指向的对象,这样就可以很优雅的移除work了。

  1. #include <boost/asio.hpp>   
  2. #include <boost/shared_ptr.hpp>   
  3. #include <iostream>   
  4.   
  5. int main( int argc, char * argv[] )  
  6. {  
  7.     boost::asio::io_service io_service;  
  8.     boost::shared_ptr< boost::asio::io_service::work > work(  
  9.         new boost::asio::io_service::work( io_service )  
  10.     );  
  11.   
  12.     work.reset();  
  13.   
  14.     io_service.run();  
  15.   
  16.     std::cout << "Do you reckon this line displays?" << std::endl;  
  17.   
  18.     return 0;     
  19. }  
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>

int main( int argc, char * argv[] )
{
	boost::asio::io_service io_service;
	boost::shared_ptr< boost::asio::io_service::work > work(
		new boost::asio::io_service::work( io_service )
	);

	work.reset();

	io_service.run();

	std::cout << "Do you reckon this line displays?" << std::endl;

	return 0;	
}
       io_service支持多线程,在上一篇博文中也提到过,并且说明了io_service的线程调度顺序。下面是一个多线程的例子:

  1. void WorkerThread()  
  2. {  
  3.     std::cout << "Thread Start\n";  
  4.     io_service.run();  
  5.     std::cout << "Thread Finish\n";  
  6. }  
  7.   
  8. int main( int argc, char * argv[] )  
  9. {  
  10.     boost::shared_ptr< boost::asio::io_service::work > work(  
  11.         new boost::asio::io_service::work( io_service )  
  12.     );  
  13.   
  14.     std::cout << "Press [return] to exit." << std::endl;  
  15.   
  16.     boost::thread_group worker_threads;  
  17.     forint x = 0; x < 4; ++x )  
  18.     {  
  19.         worker_threads.create_thread( WorkerThread );  
  20.     }  
  21.   
  22.     std::cin.get();  
  23.   
  24.     io_service.stop();  
  25.   
  26.     worker_threads.join_all();  
  27.   
  28.     return 0;  
  29. }  
void WorkerThread()
{
	std::cout << "Thread Start\n";
	io_service.run();
	std::cout << "Thread Finish\n";
}

int main( int argc, char * argv[] )
{
	boost::shared_ptr< boost::asio::io_service::work > work(
		new boost::asio::io_service::work( io_service )
	);

	std::cout << "Press [return] to exit." << std::endl;

	boost::thread_group worker_threads;
	for( int x = 0; x < 4; ++x )
	{
		worker_threads.create_thread( WorkerThread );
	}

	std::cin.get();

	io_service.stop();

	worker_threads.join_all();

	return 0;
}

上面用到了stop。如果我们想让io_service把当前工作队列中的所有工作执行完毕后再结束,需要用上面提到的reset智能指针的方法而不是stop,而如果采用reset方法的时候不断的往io_service的工作队列中增加新的任务,那么它将永远也不会停下来。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Boost.Asio是一个开源的跨平台网络编程库,它可以用于构建高效的异步I/O应用程序。以下是一些关于Boost.Asio的学习资源: 1. Boost.Asio官方文档:Boost.Asio的官方文档提供了详细的介绍和使用指南,包括教程、参考文档和示例代码。文档链接:https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio.html。 2. Boost.Asio学习指南:这是一篇由Boost.Asio的核心开发者编写的学习指南,它介绍了Boost.Asio的基本概念和使用方法,并提供了一些示例代码。指南链接:https://think-async.com/Asio/asio-1.18.1/doc/asio/overview/core.html。 3. Boost.Asio教程:这是一系列由Boost.Asio社区成员编写的教程,涵盖了从基础到高级的内容。教程链接:https://github.com/chriskohlhoff/asio/tree/master/asio/doc/tutorial。 4. Boost.Asio实战:这是一本关于使用Boost.Asio构建网络应用的书籍,它详细介绍了Boost.Asio的使用方法和实践经验,并提供了大量示例代码。书籍链接:https://www.oreilly.com/library/view/boostasio-c/9781785283079/。 希望这些资源能够帮助您学习和掌握Boost.Asio。 ### 回答2: boost.asio是一个基于C++的网络编程库,为开发人员提供了一套强大而灵活的工具来实现异步网络通信。 该库的教程涵盖了boost.asio的核心概念、基本用法和高级功能。首先,教程介绍了异步编程的概念,以及为什么应该使用异步编程来处理网络通信。然后,它讲解了boost.asio的核心组件,例如IoService、Socket和Buffer,以及如何使用它们进行网络连接和数据传输。 教程还会指导开发人员如何使用boost.asio处理不同类型的网络协议,例如TCP/IP和UDP。开发人员将学习如何创建服务器和客户端,并使用boost.asio的异步操作来处理连接和数据传输。教程还会介绍一些常见的网络编程任务,例如并发服务器和多线程编程,以及如何使用boost.asio来解决这些问题。 除了基本内容外,教程还涵盖了boost.asio的高级功能,例如SSL加密、定时器和信号处理。开发人员将学习如何使用SSL加密来保护网络通信,以及如何使用定时器来处理超时和延迟。此外,教程还会介绍如何使用信号处理来处理中断和异常情况。 总的来说,boost.asio教程为开发人员提供了一个全面的参考资料,帮助他们掌握这个强大的网络编程库。无论是初学者还是有经验的开发人员,都可以从中学习到如何使用boost.asio来构建高效可靠的网络应用程序。 ### 回答3: boost.asio是一个用于异步I/O操作的C++库。它提供了一个面向对象的接口,可以用于处理网络编程、文件I/O和串口通信等操作。boost.asio的设计目标是高效和可扩展性。 boost.asio教程是一个系统介绍boost.asio库的学习材料。该教程通常包含以下内容: 1. 引言:介绍boost.asio库的作用和特性。解释为什么选择boost.asio而不是其他库。 2. 环境配置:指导读者如何安装和配置boost.asio库。包括下载和安装boost库、配置编译器和连接器等步骤。 3. 基本概念:介绍boost.asio库的基本概念和术语。例如,异步操作、回调函数、handler等。 4. 网络编程:教授如何使用boost.asio库进行网络编程。包括创建Socket对象、建立连接、发送和接收数据等操作。 5. 文件I/O:介绍如何使用boost.asio库进行文件读写操作。教授如何打开文件、读取和写入数据等。 6. 串口通信:介绍如何使用boost.asio库进行串口通信。教授如何打开串口、发送和接收数据等。 7. 高级主题:介绍一些高级主题,例如多线程编程、定时器、SSL加密等。这些主题可以帮助读者更深入地理解和使用boost.asio库。 通过学习boost.asio教程,读者可以学会使用boost.asio库进行异步I/O操作。他们可以编写高性能的网络应用程序、文件处理程序和串口通信程序。同时,他们还能够了解到一些高级主题,从而扩展他们的技能和知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值