启动boost时的例程:: asio :: io_service

启动boost时的例程:: asio :: io_service

问题描述:

我想使用boost asio创建一个http客户端。为了进行结构化和优化,我研究了boost asio的示例,以了解一个好的实现应该是什么样的。启动boost时的例程:: asio :: io_service

大多数情况下,我遵循HTTP Server的结构,所以我有一个连接管理器,它拥有一组指向每个单独连接的指针。现在,这里的大不同的是,已经在server.cpp的构造异步函数被调用,即

 
acceptor_.async_accept(new_connection_->socket(), 
     boost::bind(&server::handle_accept, this, 
     boost::asio::placeholders::error)); 

,并在io_service对象是通过函数调用服务器启动winmain.cpp ::运行( ):

 
io_service_.run(); 

在我的实现,因为它是一个客户端,而不是服务器,我想等待用户调用的send()函数之前,我开始连接到服务器。因此,我已将所有连接到服务器的函数调用移入连接类。当用户请求到MSG发送到以下称为服务器:

 
resolver.async_resolve(query, 
            boost::bind(&connection::handle_resolve, boost::ref(*this), 
               boost::asio::placeholders::error, 
               boost::asio::placeholders::iterator)); 
io_service_.run(); 

我想开始在一个单独的线程每一个连接对象,这真的是我的问题的背景。我该怎么做才能获得结构化和优化的代码?

我试过了,例如HTTP Server 2的例子,设置一个io_services的线程池并分配工作给他们,这样他们才会返回,直到停止。这似乎是一个好主意,因为我会让io服务始终在后台运行。因此,我从我相当于server.cpp启动线程池,在一个线程:

 
boost::thread t(boost::bind(&geocast::enabler::io_service_pool::run, &io_service_pool_)); 

,但是从我自己的试验和错误分析,似乎之前,你已发出异步函数无法启动io_service对象, 真的吗?因为我的程序卡住了。在我的情况下,我只想在用户意味着发送POST请求或GET请求时调用async_resolve。支持我的理论; Chat Client首先调用一个async_connect并以async_read作为回调,这样他们就可以在创建客户端之后安全地调用io_service.run()。我不希望从服务器读取所有时间,只是为了能够启动io_service,因为这不是普通客户端的工作方式,对吧?如果浏览器没有从用户导航到网站的每个可能的服务器上读取数据......

如果我不使用示例2中的线程池,而是在单独的类中启动每个连接类,每个拥有自己的io_service,一切正常。但是,使用简单的循环程序来选择合适的io_service的线程池看起来非常有吸引力。对于我来说,多线程的最佳方法是什么?我只是挑剔,应该坚持一个连接一个io_service的东西?

我都试过了,作为HTTP服务器2 例如,设立的 io_services一个线程池,分配工作给他们 ,使他们不会返回,直到 停止。

当使用异步编程,我强烈建议您使用以下设计顺序:

  1. io_service与单个线程的线程
  2. 池调用一个io_service
  3. io_service每线程或其他奇特的设计

你应该只如果在分析之后,您的当前设计证明是一个瓶颈,那么请转到下一个设计。

,但是从我自己的尝试和错误 分析,似乎之前,你必须出具 异步函数无法启动 io_service对象,是真的吗?

你是正确的,io_service::run()documentation法术这一点很清楚

的run()函数阻塞,直到所有 工作已经完成,并且没有 更多的处理程序被分派,或 直到io_service已停止。

防止io_service::run()立即返回正确的方法是要排队的一些处理,或者实例化一个io_service::workobject,并保持它的范围,只要你想run()保持活跃。

+0

感谢您的好评!关于io_service :: run():我的意思是“无法启动io_service BEFORE”是这样的:我首先创建一个客户端对象,它有一个在线程中运行的函数。之后,我调用客户端类中的send()函数。现在,这变得棘手。在客户端类中,调用async_resolve()。同时,在主线程中,io_service以run()方式启动,即在主线程中首先调用send()函数,然后调用io_service.run()。但该计划只是卡住了。为什么?看起来工作()没有帮助... – 2011-05-18 13:22:05

+0

@Thomas问一个新问题,根据评论我不清楚你想要完成什么。 – 2011-05-18 16:19:29

使用ASIO时,您将放弃对ASIO的程序流控制。如果将代码更改为使用线程池,则可以共享控制权,并且请致电run_one()而不是run()。 run_one()仅将一个IO作业分派给线程,因此如果在ioservice中有多个事件,则必须多次调用run_one()。

你有没有想过产生一个新的线程作为你的老板线程,然后让你的老板线程创建一堆工作线程?你的老板线程可以调用run(),然后你的UI线程可以调用post()来发送一个新的工作单元。除了不必手动调用和调度ioservice中的任务,它还会使清理和关闭更直接,因为当调用run()时,您的老板线程会阻塞。