gpt4 book ai didi

c++ - 从作为分离线程运行的 boost::asio::io_service::work 捕获异常

转载 作者:行者123 更新时间:2023-11-30 03:43:56 25 4
gpt4 key购买 nike

我有我的应用程序主循环控制,我在其中启动一个线程来处理 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) 中抛出的异常没有被主处理循环捕获 try...catch阻止 AsioThread::Run .自然会发生这种情况,因为工作线程 t在另一个线程上,分离的,并且在导致执行错误的运行时。

我如何从分离的 boost::asio::io_service::work 接收异常线 ?我如何构造我的代码以使该逻辑起作用?

感谢您的帮助。

最佳答案

您可以在工作线程中捕获异常,将它们保存到两个线程共享的队列变量中,并在主线程中定期检查该队列。

要使用队列,您需要先将异常转换为通用类型。您可以使用 std::exceptionstring 或任何最适合您的情况。如果你绝对需要保留原始异常类的信息,你可以使用 boost::exception_ptr .

您需要的变量(这些可以是 AsioThread 的成员):

boost::mutex queueMutex;
std::queue<exceptionType> exceptionQueue;

在工作线程中运行这个函数:

void AsioThread::RunIoService(){
try{
ioService.run();
}
catch(const exceptionType& e){
boost::lock_guard<boost::mutex> queueMutex;
exceptionQueue.push(e);
}
catch(...){
boost::lock_guard<boost::mutex> queueMutex;
exceptionQueue.push(exceptionType("unknown exception"));
}
}

像这样启动工作线程:

boost::thread t(boost::bind(&AsioThread::RunIoService, this));
t.detach();

在主线程中:

while(true){
// Do something

// Handle exceptions from the worker thread
bool hasException = false;
exceptionType newestException;
{
boost::lock_guard<boost::mutex> queueMutex;
if(!exceptionQueue.empty()){
hasException = true;
newestException = exceptionQueue.front();
exceptionQueue.pop();
}
}
if(hasException){
// Do something with the exception
}
}

This blog post实现线程安全队列,您可以使用它来简化保存异常;在这种情况下,您不需要单独的互斥锁,因为它位于队列类中。

关于c++ - 从作为分离线程运行的 boost::asio::io_service::work 捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35814249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com