可以提升:asio io_service.run()在循环中不止一次调用?
我正在使用boost::asio
来建立一个异步客户端通信类。可以提升:asio io_service.run()在循环中不止一次调用?
在我的设计中,我有一个类(AsioThread
)和一个作为独立线程启动的主运行方法。这里是类方法代码:
void AsioThread::Run()
{
while (true)
{
transactionMutex.lock();
switch (asioState)
{
case (AsioStateType::Connect): // Start a connection
{
std::string address = currentCommand.arguments["address"];
std::string port = currentCommand.arguments["port"];
asioState = AsioStateType::ConnectWait;
boost::asio::ip::tcp::resolver::iterator end;
if (currentEndPoints == end)
{
boost::asio::io_service ios;
boost::asio::ip::tcp::resolver resolver(ios);
boost::asio::ip::tcp::resolver::query query(address, port);
currentEndPoints = resolver.resolve(query);
}
else
{
currentEndPoints++;
}
currentSocket->close();
currentSocket->async_connect(*currentEndPoints, boost::bind(&AsioThread::ConnectHandler, this, _1));
break;
}
case (AsioStateType::ConnectResponse): // Receive connection welcome message
{
asioState = AsioStateType::ConnectResponseWait;
currentSocket->async_receive(boost::asio::buffer(boost::asio::buffer(rxBuffer, MAX_BUFFER_SIZE)), 0, boost::bind(&AsioThread::ReceiveDataHandler, this, _1, _2));
break;
}
}
transactionMutex.unlock();
ioService.run();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
有了这段代码,回调函数永远不会被调用。如果我将ioService.run()放在async_connect或async_receive行之后,则会调用它来进行连接 - 而不是接收消息。另外,如果我添加调试线,如:
`std::cout << "I´m here " << std::endl´
有时回调是所谓的,这取决于我把这个调试代码的地方。
对我来说,我错了,使用ioService.run()
。请注意,每次循环传递都会调用它(每秒10次)。
互斥量用于控制其他线程对asioState
的写入访问 - 其他线程通过使用此成员变量传递的消息来命令此主循环操作。
帮助表示赞赏找到出路what's错在这里...
当io_service::run()
用完的工作,它返回。在异步操作之后调用ioService.run()
时发生的情况是,它允许该操作完成,然后耗尽工作并返回。排队下一个操作后,您需要运行到io_service
以处理操作。
另一种方法是在提交boost::io_service::work
对象以保持活动状态后,让线程运行ioService::run()
。要处理switch语句中的情况,您可以使用io_service::post()
触发操作,以便在运行处理程序内运行它们而不是轮询状态变量。当你想关闭线程时,销毁工作对象。
我没有得到你说的那句话:“在将下一个操作排队后,你需要运行io_service来处理操作。”我在每次交互时调用ioService.run()... – Mendes
如果io_service耗尽工作,它将处于“stopped()”状态。你需要“重置()”来让它在你完成一些工作后再做更多的工作。 –
这不是使用asio的方式。阅读文档中的示例。 http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp03/http/client/async_client.cpp –
你的意思是只有一种方法可以使用asio? – Mendes
不,有几种方法,但是从线程或线程池中为io服务提供服务是使用它的特定方式,并且存在正确的习惯用法。您需要创建一个工作对象以防止io服务停止。当您希望工作线程停止时,请在io服务上调用stop()。 –