为什么不能使用C++;例外情况? 我在C++中阅读思维(异常处理)。< /P>

为什么不能使用C++;例外情况? 我在C++中阅读思维(异常处理)。< /P>,c++,exception-handling,C++,Exception Handling,我听不懂下面这句话 C++异常不能用于处理异步事件,因为异常及其处理程序位于同一调用堆栈上 我试图在网上搜索,但无法理解这一行。(特别是调用堆栈部分) 有人能帮忙吗 编辑: 相同的调用堆栈意味着什么?异常在抛出时,将当前线程的执行路径转移到处理该异常。没有办法通过让另一个线程执行异常处理来避免这种情况。堆栈在这里很重要,因为异常处理涉及堆栈展开,这不利于asyncronouis事件处理或其他许多事情。问题是这样的 try { dispatch_async(dispatch_get_glo

我听不懂下面这句话

C++异常不能用于处理异步事件,因为异常及其处理程序位于同一调用堆栈上

我试图在网上搜索,但无法理解这一行。(特别是调用堆栈部分) 有人能帮忙吗

编辑:
相同的调用堆栈意味着什么?

异常在抛出时,将当前线程的执行路径转移到处理该异常。没有办法通过让另一个线程执行异常处理来避免这种情况。堆栈在这里很重要,因为异常处理涉及堆栈展开,这不利于asyncronouis事件处理或其他许多事情。

问题是这样的

try {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // do some really long running operation here
        longFunctionToCalculate42();

        // oops, some critical error!
        throw std::runtime_error( "Something went wrong!" );
    });
} catch ( const std::exception& e ) {
    // this won't do what you think it does
    std::cerr << e.what() << std::endl;
}
试试看{
调度异步(调度获取全局队列(调度队列优先级默认为0)^{
//在这里做一些长时间运行的操作
长函数计算42();
//哎呀,一些严重的错误!
抛出std::runtime_error(“出错了!”);
});
}捕获(const std::exception&e){
//这不会像你想象的那样

std::cerr实际上,您可以使用异常处理异步事件。您是否应该是另一回事。我只简单介绍一下:您通常不应该这样做,因为有更多的直接机制来处理此类事件。例如在线程之间传递消息或引发某种事件

至于如何实现这一点,您需要做的是
捕获
抛出
-ing线程中的异常,将信息记录在某个位置,然后让另一个线程拾取。请注意,这实际上归结为线程之间的消息传递,增加了堆栈展开和喜欢

C++11提供了,返回a,它提供了将异常信息保存到响应线程可以拾取它的某个位置的方法。仍然由您来构建代码,从您保存异常的位置实际检索和处理该异常,这超出了本回答的范围


考虑到这一点时,请注意,除非您需要实际的异常,否则这样做只会在线程之间传递消息,而不会带来任何好处,并且会花费堆栈展开以及抛出和捕获异常的语义含义。

这意味着异步事件不遵循异常的模型,其中“异常及其处理程序位于同一调用堆栈上”-

异常依赖于程序上函数调用的动态链 s运行时堆栈(它们具有动态范围),而异步 事件必须由完全独立的代码处理,该代码不是 正常程序流(通常为中断服务例程或 事件循环)


请注意“完全独立的代码”,这意味着您必须依赖其他机制来处理异步事件(如果您确实需要)。

切勿使用异常来模拟逻辑路径上的程序流。只需将它们用于异常错误情况。@πάνταῥεῖ: 一个异步事件并不是一个异常的错误情况。问题可能是问线程之间如何交换异常,但是如果是这样的话,这一点就不太清楚了。想象一下,如果异步地抛出一个异常,比如说,在<代码>中间的STD::(x,y)
。在异步代码中可以安全完成的事情很少。一个线程至少有自己的堆栈和异常处理(EH)上下文。异步代码无法将异常向上传递到调用堆栈,因为被中断的函数无法知道异常是否可能,也无法知道异常发生在函数中的什么位置。实际上,有一些功能可以从线程交换/传播异常:@paul我理解您的观点,即堆栈解除ng需要做。但是共享同一个调用堆栈意味着什么?@Suri'但是共享同一个调用堆栈意味着什么?'这只是一个事实,不同的线程根据定义从来不会共享同一个调用堆栈。每个线程有一个调用堆栈,这就是同一个调用堆栈,每个线程可以捕获所有抛出的异常。@πάνταῥεῖ 我可以从处理程序中抛出异常,因为我将知道当前程序暂停的位置吗?