我正在使用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錯在這裏...
這不是使用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()。 –