One*_*Pie 7 c++ multithreading exception c++11 visual-studio-2012
我有一个程序需要将异常从任何未被捕获的线程传播到主线程,以便它可以向用户提供有关失败原因和安全关闭的信息.我的InterThreadException处理程序似乎工作,但只有当抛出异常的线程由主线程直接生成时.
该InterTheadException处理器在所有情况下都正确地调用,而被发信具有传递给它的异常指针的异常传播,并在主线程接收到它已经收到了新的异常通知,但调用std::rethrow_exception的异常指针只是失败似乎什么也没做.我已经测试过从这两个不同的线程中抛出完全相同的异常,并且无论我抛出什么,问题似乎都会持续存在.
我怀疑我对如何使用异常指针有一个基本的误解,但我不确定.
这是我的实施InterThreadExceptionHandler.
class InterThreadExceptionHandler : NonCopyable
{
public:
InterThreadExceptionHandler();
~InterThreadExceptionHandler();
//
// Sends an exception into this handler, informing it that
//this exception has been caught
// and may be propagated to another thread
//
void sendException(std::exception_ptr exception);
//
// Freezes the calling thread until an exception has been sent,
//then rethrows said exception
//
void waitForException();
private:
std::vector<std::exception_ptr> sentExceptions;
std::mutex sentExceptionsMutex;
Semaphore sentExceptionsCounter;
};
InterThreadExceptionHandler::InterThreadExceptionHandler()
{
}
InterThreadExceptionHandler::~InterThreadExceptionHandler()
{
}
void InterThreadExceptionHandler::sendException(std::exception_ptr exception)
{
ScopedLock lock(this->sentExceptionsMutex);
this->sentExceptions.push_back(exception);
this->sentExceptionsCounter.give();
}
void InterThreadExceptionHandler::waitForException()
{
this->sentExceptionsCounter.take();
ScopedLock lock(this->sentExceptionsMutex);
assert( this->sentExceptions.size() > 0 );
std::exception_ptr e = this->sentExceptions[0];
this->sentExceptions.erase(this->sentExceptions.begin());
if (e == std::exception_ptr())
{
throw std::exception("Invalid exception propagated!");
}
std::rethrow_exception(e);
}
Run Code Online (Sandbox Code Playgroud)
很抱歉这不是您问题的直接答案,但无论如何它可能会有所帮助。
如果我通过捕获异常、检查返回代码等方式检测到线程中的运行时错误,我会让该线程冻结整个进程。我还将让它关闭 ftracing(dtrace 的 Linux 克隆),以便保留我可以获得的任何跟踪日志,以防止出现问题。恐怕我不知道 Windows 中的对应项是什么。然后我可以附加一个调试器并环顾四周看看发生了什么,甚至可以更正一个值并继续执行。
它在部署的代码中不太有用,但在开发过程中却非常有用。人们对问题的看法是好的,因为一切都“按原样”存在,没有堆栈展开,其他线程没有太多机会到达任何地方,等等。这可以使故障识别更容易。对于已部署的代码,我可能会引发核心转储(我倾向于在 unixy 上运行)。显然,如果需要某种程度的清理,那就不好了。
| 归档时间: |
|
| 查看次数: |
578 次 |
| 最近记录: |