【发布时间】:2016-03-05 12:41:42
【问题描述】:
我有我的应用程序主循环控制,我在其中启动一个线程来处理 asio 工作,如下所示:
void AsioThread::Run()
{
try
{
/*
* Start the working thread to io_service.run()
*/
boost::asio::io_service::work work(ioService);
boost::thread t(boost::bind(&boost::asio::io_service::run, &ioService));
t.detach();
while (true)
{
// Process stuff related to protocol, calling
// connect_async, send_async and receive_async
}
}
catch (std::runtime_error &ex)
{
std::cout << "ERROR IN FTP PROTOCOL: " << ex.what() << std::endl;
}
catch (...)
{
std::cout << "UNKNOWN EXCEPTION." << std::endl;
}
在异步操作期间,处理程序被调用,有时我会在这些处理程序上抛出异常,例如:
void AsioThread::ReceiveDataHandler(const boost::system::error_code& errorCode, std::size_t bytesTransferred)
{
std::cout << "Receive data handler called. " << bytesTransferred << " bytes received." << std::endl;
if (errorCode)
{
std::cout << "Error receiving data from server." << std::endl;
}
rxBufferSize = bytesTransferred;
/*
* Check for response
*/
std::string msg(rxBuffer);
if (msg.substr(0, 3) != "220")
throw std::runtime_error("Error connecting to FTP Server");
}
我的问题是异步处理程序 (AsioThread::ReceiveDataHandler) 中抛出的异常没有被AsioThread::Run 中的主处理循环try...catch 块捕获。自然会发生这种情况,因为工作线程 t 在另一个线程上,处于分离状态,并且在运行时会导致执行错误。
如何从分离的boost::asio::io_service::work 线程接收异常?如何构建我的代码以使这个逻辑起作用?
感谢您的帮助。
【问题讨论】:
-
为什么会有一个单独的
while (true)事件循环?你可以只使用 asio 事件循环来做所有事情吗?在这种情况下加入线程。如果它可以用完工作,请创建一个 io_service::work 对象。 -
我需要事件循环,因为它作为协议逻辑的状态处理器......没有它就无法实现。
-
不确定我是否理解你,但通常协议状态是在异步回调中处理的。不需要为此设置单独的事件循环。例如,在 async_connect 之后的回调中,您将被连接等。事件处理程序启动下一个异步操作,例如async_connect 处理程序也可以开始读取和写入。
-
是的,这就是正在做的事情,但是整个逻辑运行从客户端类调用,该类向 maon 循环发送和接收命令,如 Connect、SendFile 等......这就是为什么我确实有一个接收这些消息的主循环......就像嵌入协议的命令控制概念......
-
为什么异常需要传播到
AsioThread::Run()?是否只退出while循环?您能否提供一个关于while(true)循环在做什么的代码示例?这个问题感觉像是XY problem,是当前设计的结果。
标签: c++ multithreading boost boost-asio