C++ 启动boost::asio::io_服务时的例程
我想使用boost asio创建一个http客户端。为了有一个结构化和优化的应用程序,我研究了boost asio的示例,以了解一个好的实现应该是什么样子 大多数情况下,我遵循的是的结构,因此我有一个连接管理器,它保存一组指向每个单独连接的指针。现在,这里最大的区别是在server.cpp的构造函数中已经调用了一个异步函数,即 acceptor_.async_accept(new_connection_->socket(), boost::bind(&server::handle_accept, this, boost::asio::placeholders::error)); acceptor\异步\u accept(新建\u连接->套接字(), boost::bind(&server::handle_accept),这, boost::asio::占位符::错误); 在winmain.cpp中,io_服务通过对server::run()的函数调用启动: io_服务_uu.run(); 在我的实现中,因为它是一个客户端而不是服务器,所以我希望在开始连接到服务器之前等待用户调用send()函数。因此,我将所有与服务器连接相关的函数调用移到了connection类中。当用户请求向服务器发送消息时,调用以下命令: resolver.async_resolve(query, boost::bind(&connection::handle_resolve, boost::ref(*this), boost::asio::placeholders::error, boost::asio::placeholders::iterator)); io_service_.run(); 解析程序.async\u解析(查询, boost::bind(&connection::handle_resolve,boost::ref(*this), boost::asio::占位符::错误, boost::asio::占位符::迭代器); io_服务_uu.run(); 我想在一个单独的线程中启动每个连接对象,这就是我问题的背景。我如何做到这一点,以获得结构化和优化的代码 例如,我尝试设置io_服务的线程池,并将工作分配给它们,以便它们在停止之前不会返回。这似乎是个好主意,因为我会让io服务一直在后台运行。因此,我从等效于server.cpp的线程池启动线程: boost::thread t(boost::bind(&geocast::enabler::io_service_pool::run, &io_service_pool_)); boost::线程t(boost::bind(&geocast::enabler::io_服务_池::运行,&io_服务_池)); 但是,根据我自己的试错分析,在发出异步函数之前,似乎无法启动io_服务,这是真的吗?因为我的程序卡住了。在我的例子中,我只想在用户想要发送POST请求或GET请求时调用async_resolve。支持我的理论;首先调用一个async_connect并将async_读取为回调,这样他们就可以在创建客户端之后安全地调用io_service.run()。我不想为了启动io_服务而一直从服务器上读取数据,因为这不是普通客户端的工作方式,对吗?如果用户没有浏览到某个网站,浏览器就无法读取地球上所有可能的服务器 如果我不使用示例2中的线程池,而是在一个单独的类中启动每个连接类,每个类都有自己的io_服务,那么一切都可以正常工作。但是,一个线程池和一个简单的循环例程来选择合适的io_服务似乎真的很吸引人。对于我来说,使用多线程的最佳方法是什么?我只是挑剔,应该坚持一个连接一个io的服务吗 我已经试过了,作为HTTP服务器2 例如,设置的线程池 io_服务和分配工作给他们 这样他们就不会回来,直到 停下来 在使用异步编程时,我强烈建议按顺序使用以下设计:C++ 启动boost::asio::io_服务时的例程,c++,multithreading,boost-asio,boost-thread,C++,Multithreading,Boost Asio,Boost Thread,我想使用boost asio创建一个http客户端。为了有一个结构化和优化的应用程序,我研究了boost asio的示例,以了解一个好的实现应该是什么样子 大多数情况下,我遵循的是的结构,因此我有一个连接管理器,它保存一组指向每个单独连接的指针。现在,这里最大的区别是在server.cpp的构造函数中已经调用了一个异步函数,即 acceptor_.async_accept(new_connection_->socket(), boost::bind(&server::handle_a
io_服务
io\u服务的线程池
io_服务
每线程或其他异国设计io\u服务::run()
非常清楚地说明了这一点
函数的作用是:直到所有
工作已经完成,没有工作了
要分派更多处理程序,或
直到io_服务停止
防止
io\u service::run()
立即返回的正确方法是将一些处理程序排队,或实例化io\u service::work
,并将其保持在范围内,直到run()
保持活动状态。使用ASIO时,您放弃了对ASIO程序流的控制。如果您将代码更改为使用线程池并调用而不是调用,则可以共享控制权。run_one()只将一个IO作业分派给一个线程,因此如果ioservice中有多个事件,则必须多次调用run_one()
您是否想过生成一个新线程作为您的boss线程,然后让您的boss线程创建一组工作线程?您的boss线程可以调用run(),然后您的UI线程可以调用以分派新的工作单元。除了不必在ioservice中手动调用和调度任务外,它还可以使清理和关闭更直接,因为您的boss线程在调用run()时会阻塞。感谢您的良好反馈!关于io_服务::run():我所说的“之前无法启动io_服务”的意思是:我首先创建一个客户端对象,它有一个在线程中运行的函数。然后调用客户端类中的send()函数。现在,这就是它变得棘手的地方;在客户机类中,调用async_resolve()。同时,在主线程中,io_服务通过run()启动,即在主线程中首先调用send()函数,然后调用io_服务.run()。但是这个程序只是被卡住了。为什么?“看来work()帮不了什么忙……”托马斯问了一个新问题,我不清楚根据评论你想完成什么。 boost::thread t(boost::bind(&geocast::enabler::io_service_pool::run, &io_service_pool_));