使用boost :: asio和boost :: io_service
时,我遇到了两难境地我的类环绕了由套接字连接提供的async client example。 我使用另一个封装的类:
class service_controller
{
...
/// IO service
boost::asio::io_service __io_service;
/// Endpoint Resolver
boost::asio::ip::tcp::resolver::query __query;
/// Resolution for TCP
boost::asio::ip::tcp::resolver __resolver;
}
因此,当我构造我的客户端时,构造函数接受引用:
asio_service_client (
boost::asio::ip::tcp::resolver::query & query,
boost::asio::ip::tcp::resolver & resolver,
boost::asio::io_service & io_service
);
一切正常,但我必须致电
io_service.run()
最后,在创建了所有客户之后。 如果我为每个客户端封装单独的io_service对象,我基本上删除了异步io性质,因为每个客户端将阻塞直到它完成。 因此,我决定通过使所有客户端对象使用相同的io_service来形成一种类型的组。
io_service :: poll()似乎根本不起作用(没有任何反应),io_service :: run_one()也没有。
事实上,唯一可行的方法是:
// with a callback => the callback will run once finished
rapp::services::asio_service_client c1( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
// without a callback => asio_service_client::handle_reply will run once finished
rapp::services::asio_service_client c2 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
rapp::services::asio_service_client c3 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
rapp::services::asio_service_client c4 ( ctrl.Query(), ctrl.Resolver(), ctrl.Services() );
// Run services c1, c2
c1.Run( header, post,
[&]( boost::asio::streambuf & buffer )
{
std::string raw ( ( std::istreambuf_iterator<char>( &buffer ) ), std::istreambuf_iterator<char>() );
std::cout << raw << std::endl;
});
c2.Run( header, post );
ctrl.Services().run();
/// Run remaining services ( c3, c4 )
c3.Run( header, post );
c4.Run( header, post );
ctrl.Services().reset();
ctrl.Services().run();
当然,除非我要求一个小组完全运行(例如,要求c1,c2,c3和c4运行)。
是否有某种方式或某种类模式,我可以自动化队列,在那里我创建对象,添加它们,它们是异步运行的?理想情况下使用线程,但没有线程也可以工作。
某种堆栈,在我添加对象时,它们会被异步执行,因为它们被添加。
如果我尝试这样的话:
Scheduler::Execute ( asio_service_client & client )
{
client.Run( ... )
io_service.reset();
io_service.run();
}
我将重置以前运行的服务,并从头开始,这不是我想要的。 我唯一明显的选择是接受并为每个添加的asio_service_client分配一个单独的io_service,还是强制它们在作业组中一起添加,然后执行?
我能想到的另一个解决方案是使用线程,因此,每个asio_service_client都会在自己的线程中运行,因此不会阻止其他asio_service_clients,并行执行?
答案 0 :(得分:2)
您可能希望共享一个io_service
实例并在其上发布io_service::work
对象,以便即使没有客户端当前有任何挂起的asycn操作,它也会保持活动状态:
boost::asio::io_service io_service;
auto work = boost::make_shared<boost::asio::io_service::work>(io_service);
// any client can post it's asynchronous operations on this service object, from any thread
// completion handlers will be invoked on any thread that runs `io_service.run()`
// once you want the `io_service` to empty the queue and return:
work.reset();
// now `run()` will return when it runs out of queued tasks