// asio_ioservice.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <iostream> /* asio是boost提供的一个c++异步编程模型库,其核心类io_service,在多线程编程里面提供了任务队列和任务分发功能, 在socket、io编程里主要作为一个事件驱动器(完成端口、select、poll、epoll等)。以下是我们常用对象: boost::asio::ip::tcp::socket boost::asio::ip::tcp::acceptor boost::asio::ip::udp::socket 这些对象的构造函数里都有一个必须的参数就是io_service&,也就是说每个异步对像都需要1个io_service。但可以共用一个公共的io_service。 */ int test_run() { 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; } /* 运行这个示例,我们获得之前同样的输出。因为poll函数在没有任务运行时候不 会阻塞。poll函数简单执行当前任务组并且返回。 选择poll函数或者run函数取决于函数的设置。这些函数带来更多的兼容性,程序 员可以更好的调整程序。run函数将阻塞并等待任务,poll函数则不。 */ int test_poll() { boost::asio::io_service io_service; ///< work是一个很小的辅助类,只支持构造函数和析构函数。 - 2018/05/14 ///< 因此work如果析构,则io.run会在处理完所有消息之后正常退出。work如果不析构,则io.run会一直运行不退出。如果用户直接调用io.stop,则会让io.run立刻退出。 - 2018/05/14 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; } /* 如果我们想从io_service移除一个work对象。通过查看文档,没有函数提供此种 功能。为了实现此种功能,我们必须使用work对象的智能指针。 程序显示如何让从io_service移除work对象,这个功能对于我们优雅的关闭一个挂起的任务很重要。 */ int test_shared_ptr() { boost::asio::io_service io_service; ///< io_service::work类可以使io_service::run函数在没有任务的时候仍然不返回,直至work对象被销毁。 - 2018/05/14 boost::shared_ptr< boost::asio::io_service::work > work( new boost::asio::io_service::work(io_service) ); ///< 如果不调用reset,io.run会一直阻塞直到work析构掉 - 2018/05/14 work.reset(); ///< Run方法执行队列中的所有任务,直到任务执行完毕。 io_service.run(); std::cout << "Do you reckon this line displays?" << std::endl; return 0; } /* 注意:stop的作用->阻止队列外新的任务 不要期待stop能停止run线程退出,如果任务队列执行的时间较长,只有任务执行完成之后,run线程才真正退出; stop函数的意义是阻止任务队列接收外面新的任务,比如stop之后再post任务,此时post无效。 假如stop之后任务队列还有一条未执行完的任务,在此任务执行完之前外面析构或是反初始化此条任务需要使用的实例对象,当然会产生core。 所以不能想当然认为stop就是run线程退出了,让任务队列里面任务不再执行,那是不行的。 stop阻止任务队列接收新任务,并在执行完成之后退出run线程,若已存在任务队列中的任务一直无法执行完,则无法退出run线程。 */ /* reset()的作用 在Windows下,boost::asio::io_service类里面有一个数据成员为"stopped_"(Flag to indicate whether the event loop has been stopped.)。 它是一个标志,它标志着事件循环是不是被stopped了。 而boost::asio::io_service::reset()函数仅仅是赋值"stopped_=0"。 简而言之,io.stop()负责阻止队列外新任务,work.reset()将_stop的标志位置位为0; */ int _tmain(int argc, _TCHAR* argv[]) { test_poll(); test_shared_ptr(); system("pause"); return 0; }
// Test_ThreadPool.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <iostream> boost::asio::io_service io_service; /* 程序显示如何让从io_service移除work对象,这个功能对于我们优雅的关闭一个挂起的任务很重要。 多线程下呼叫run函数设置执行处理器的线程池。池中等待的线程是同等优先级,io_service随机选择一个触发处理器。 */ void WorkerThread() { std::cout << "Thread Start\n"; io_service.run(); std::cout << "Thread Finish\n"; } /* 示例介绍stop成员函数。 stop成员函数将发信号给io_service,提示所有任务将停止。 所以在当前任务结束后,不再有任务发起。示例中另一个变化就是io_service对象成为全局对象。 运行程序后将有4个线程开始传输信息,并且在我们敲击回车后停止。 */ 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(); system("pause"); return 0; }