C++: 跨线程异常处理问题与 boost::exception

标签 c++ multithreading exception boost exception-handling

基本上,我遇到过这样一种情况:一个线程抛出异常,而另一个线程需要处理该异常。我正在尝试使用 boost 异常来执行此操作,但是异常丢失了它的类型,因此没有被 catch block 捕获。

基本上,线程 B 想要做某事,但是由于各种原因,它必须由线程 A 完成(如果您想知道这些原因,请询问 MS 为什么 direct3d 9 设备必须由与它相同的线程创建、重置和释放创建窗口)。如果在执行这些操作时发生异常,线程 A 会捕获它,将其传递回线程 B,然后线程 B 重新抛出它以根据需要进行处理。问题是线程 B 中抛出的异常似乎与线程 A 中抛出的异常不同。:(

我程序的调试输出和代码如下。

First-chance exception at 0x776b42eb ...: fllib::exception::Error at memory location 0x0019e590..  
First-chance exception at 0x776b42eb ...: [rethrow] at memory location 0x00000000..  
First-chance exception at 0x776b42eb ...: boost::exception_detail::clone_impl<boost::unknown_exception> at memory location 0x0019eed4..
//thread B
...
try
{
    SendCallback(hwnd, boost::bind(&Graphics::create, this));
}
catch(fllib::exception::Error &except)//example catch block, doesnt catch example exception
{
    ...handle exception...
}

void SendCallback(HWND hwnd, boost::function<void()> call)
{
    boost::exception_ptr *except_ptr = 
        (boost::exception_ptr*)SendMessage(hwnd, WM_CALLBACK, (unsigned)&call, SEND);
    if(except_ptr)//if an exception occurred, throw it in thread B's context
    {
        boost::exception_ptr except = *except_ptr;
        delete except_ptr;
        boost::rethrow_exception(except);
    }
}
//thread A
LRESULT CALLBACK HookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    //check for our custom message
    if(msg == WM_CALLBACK)
    {
        if(lParam == POST)
        {
            ...
        }
        else
        {
            boost::function<void()> *call = (boost::function<void()>*)wParam;
            try
            {
                (*call)();
            }
            catch(...)
            {
                return (unsigned)new boost::exception_ptr(boost::current_exception());
            }
            return 0;
        }
    }
    else
    {
        ...
    }
}

void Graphics::create()
{
...code that may throw exceptions...
eg
    throw fllib::exception::Error(L"Test Exception...");
}

最佳答案

确保线程 A 的每次抛出都使用 boost::enable_current_exception 包装器。参见 this .

"Unless enable_current_exception is called at the time an exception object is used in a throw-expression, an attempt to copy it using current_exception may return an exception_ptr which refers to an instance of unknown_exception."

为此,您可能需要捕获线程 A 中的所有异常,并在用 throw boost::enable_current_exception(your_exception) 包装它们后重新抛出它们。

此外,这不适用于除零之类的结构化异常,除非您使用 _set_se_translator调用包装器并将它们包装在异常对象中。

关于C++: 跨线程异常处理问题与 boost::exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/667077/

相关文章:

c++ - 如何在C++中使用原子防止关键部分访问

java - 未报告的异常 IOException 从 URL 读取文件

java - 如何重新抛出捕获的异常

exception - 如何拦截Tomcat 上未捕获的异常?

c++ - dijkstra 的恒权最短路径算法

c# - 有人可以解释 URI 类重载版本中的 RelativeOrAbsolute 参数吗?

android - Sugar ORM 在初始化时阻塞 UI 线程

java - 在另一个线程上有益地执行一件工作的最小尺寸?

c++ - wav 的 Audio Visualizer 看起来不对

c++ - const char * 数组中的元素数