改进基于Boost.Asio的聊天服务

  Boost.Asio是个非常易用的C++异步网络库,官方文档中一个示例是聊天服务,分为chat_message、chat_client、chat_server三个部分。chat_server的启动代码如下。

 1     if (argc < 2)
 2     {
 3       std::cerr << "Usage: chat_server <port> [<port> ...]\n";
 4       return 1;
 5     }
 6 
 7     boost::asio::io_service io_service;
 8 
 9     chat_server_list servers;
10     for (int i = 1; i < argc; ++i)
11     {
12       using namespace std; // For atoi.
13       tcp::endpoint endpoint(tcp::v4(), atoi(argv[i]));
14       chat_server_ptr server(new chat_server(io_service, endpoint));
15       servers.push_back(server);
16     }
17 
18     io_service.run();

  从中可以看出,输入多个端口号会启动多个chat_server,但只有一个io_service,也就是说多个chat_server中产生的异步任务handler被放入同一个任务队列(由唯一的io_service维护),这就相当于用一个线程同时处理多个聊天服务器,自然会对系统的性能产生影响。

  从io_service_pool这个示例中可以得到一点改进的启发,每个chat_server绑定一个io_service,每个io_service在一个独立的线程中运行,这样就能充分利用机器的多核性能,改进代码如下。

 1         if (argc < 2)
 2         {
 3             std::cerr << "Usage: chat_server <port> [<port> ...]\n";
 4             return 1;
 5         }
 6 
 7         typedef boost::shared_ptr<boost::asio::io_service> io_service_ptr;
 8         typedef std::list<io_service_ptr> io_service_list;
 9 
10         chat_server_list servers;
11         io_service_list services;
12         for (int i = 1; i < argc; ++i)
13         {
14             using namespace std; // For atoi.
15             tcp::endpoint endpoint(tcp::v4(), atoi(argv[i]));
16             io_service_ptr service(new boost::asio::io_service);
17             chat_server_ptr server(new chat_server(*service, endpoint));
18             services.push_back(service);
19             servers.push_back(server);
20         }
21 
22         std::vector<std::shared_ptr<std::thread> > threads;
23         for(auto service : services) 
24         {
25             auto run_func = [](const io_service_ptr& ptr) {
26                 return ptr->run();
27             };
28             std::function<std::size_t()> f = std::bind(run_func, service);
29             std::shared_ptr<std::thread> thread(new std::thread(f));
30             threads.push_back(thread);
31         }
32 
33         // Wait for all threads in the pool to exit.
34         for (std::size_t i = 0; i < threads.size(); ++i) {
35             threads[i]->join();
36         }    

 

posted @ 2014-11-21 00:45  Chris Lee  阅读(525)  评论(0编辑  收藏  举报