我正在使用boost::asio
构建异步客户端通信类。
在我的设计中,我有一个类(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));
}
}
使用此代码,永远不会调用回调。如果我在async_connect或async_receive行之后放置ioService.run(),则会调用它来进行连接 - 而不是用于消息接收。如果我添加调试行,如:
`std::cout << "I´m here " << std::endl´
有时会调用回调,具体取决于我放置此调试代码的位置。
对我来说,使用ioService.run()
我错了。请注意,每次循环传递都会调用它(每秒10次)。
互斥锁用于控制其他线程对asioState
的写访问权限 - 其他线程通过使用此成员变量传递的消息来命令此主循环操作。
帮助感谢在这里找出错误的方法...
答案 0 :(得分:1)
当io_service::run()
用尽时,它会返回。在异步操作之后调用ioService.run()
时发生的事情是它允许该操作完成,然后用完并返回。排队下一个操作后,需要运行到io_service
来处理操作。
另一种方法是在提交ioService::run()
对象后让一个只运行boost::io_service::work
的线程使其保持活动状态。要处理switch语句中的情况,可以使用io_service::post()
触发操作以在运行处理程序内运行它们,而不是轮询状态变量。如果要关闭线程,请销毁工作对象。