Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 捕获boost::asio::io_服务::工作作为分离线程运行的异常_C++_Multithreading_Boost_Boost Asio - Fatal编程技术网

C++ 捕获boost::asio::io_服务::工作作为分离线程运行的异常

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(&

我有我的应用程序主循环控制,在这里我启动一个线程来处理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::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
    }
}