C++ 捕获boost::asio::io_服务::工作作为分离线程运行的异常
我有我的应用程序主循环控制,在这里我启动一个线程来处理asio工作,如下所示:C++ 捕获boost::asio::io_服务::工作作为分离线程运行的异常,c++,multithreading,boost,boost-asio,C++,Multithreading,Boost,Boost Asio,我有我的应用程序主循环控制,在这里我启动一个线程来处理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(&
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::Run()
{
尝试
{
/*
*启动io_服务的工作线程。运行()
*/
boost::asio::io_service::work-work(ioService);
boost::线程t(boost::bind(&boost::asio::io_服务::run,&ioService));
t、 分离();
while(true)
{
//处理与协议相关的内容,调用
//连接异步、发送异步和接收异步
}
}
捕获(标准::运行时错误和ex)
{
std::cout您可以捕获工作线程中的异常,将它们保存到两个线程共享的队列变量中,并在主线程中定期检查该队列
要使用队列,您需要首先将异常转换为通用类型。您可以使用std::exception
或string
或任何最适合您情况的方法。如果您绝对需要保留原始异常类的信息,您可以使用
您需要的变量(这些变量可以是AsioThread
的成员):
在主线程中:
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
}
}
while(true){
//做点什么
//处理工作线程中的异常
bool hasException=false;
异常类型newestException;
{
boost::lock_guard queueMutex;
如果(!exceptionQueue.empty()){
hasException=true;
newestException=exceptionQueue.front();
exceptionQueue.pop();
}
}
如果(hasException){
//做一些例外的事情
}
}
实现一个线程安全队列,您可以使用它来简化保存异常;在这种情况下,您不需要单独的互斥,因为它位于队列类内部。为什么要使用单独的while(true)
事件循环?您可以使用asio事件循环来完成所有操作?在这种情况下,请加入线程。如果它可能无法正常工作,请创建一个io_service::work对象。我需要事件循环,因为它可以作为procotol逻辑的状态处理器工作……没有它就无法完成。我不确定是否理解您的意思,但通常会处理协议状态在异步回调中。不需要为此设置单独的事件循环。例如,在异步连接之后的回调中,您将被连接,等等。事件处理程序启动下一个异步操作,例如,异步连接处理程序也可以启动读写。是的,这就是正在进行的操作,但整个逻辑运行时称为fro我是一个向maon循环发送和接收命令的客户机类,如Connect、SendFile等…这就是为什么我有一个主循环来接收这些消息…如嵌入协议的命令控制概念…为什么需要将异常传播到AsioThread::Run()
?是否只从while
循环中退出?请提供一个代码示例,说明while(true)是什么
loop在做什么?这个问题感觉像是一个问题,也是当前设计的结果。这是一个好主意,但我没有对工作线程进行编码…它由boost::asio
处理。请参阅boost::thread t(boost::bind(&boost::asio::io_service::run,&ioService))当您可能无法控制<代码> IOSService::()(代码)>时,您确实可以控制线程的入口点。请考虑创建一个函数,调用<代码> IoService .Run()
在try/catch块中,根据需要传播异常,并将此函数指定为线程入口点。@Mendes我更改了答案,在您的情况下它现在应该可以工作了。
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
}
}