Tôi có một chương trình cần truyền bá ngoại lệ từ bất kỳ chuỗi không bắt buộc nào đến luồng chính, để nó có thể cung cấp cho người dùng thông tin về lý do không thành công và tắt an toàn. Trình xử lý InterThreadException
của tôi dường như hoạt động nhưng chỉ khi luồng gửi một ngoại lệ được sinh ra trực tiếp bởi luồng chính.std :: rethrow_exception thất bại với các chủ đề lồng nhau
Trình xử lý InterTheadException
được gọi chính xác trong mọi trường hợp, được báo hiệu rằng một ngoại lệ được truyền bằng cách có con trỏ ngoại lệ được chuyển đến nó và chuỗi chính nhận được thông báo rằng nó đã nhận được ngoại lệ mới, nhưng gọi đến std::rethrow_exception
trên con trỏ ngoại lệ chỉ đơn giản là thất bại và dường như không làm gì cả. Tôi đã thử nghiệm ném chính xác cùng một ngoại lệ từ hai chủ đề khác nhau, và vấn đề dường như vẫn tồn tại không có vấn đề gì tôi ném.
Tôi nghi ngờ mình có hiểu lầm cơ bản về cách người ta phải sử dụng con trỏ ngoại lệ, nhưng tôi không chắc chắn.
Đây là triển khai của tôi về số 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);
}
bản sao có thể có của http://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads – engineerC
Lớp học của bạn hoạt động tốt với GCC trên GNU/Linux (sau khi thay đổi 'count()' tới 'size()' và thay đổi lời gọi thành hàm dựng non 'std :: exception' và thay thế' Semaphore' bằng 'std :: condition_variable') để nó giống như một lỗi MSVC. Nó không quan trọng cho dù một thread được sinh ra bởi chủ đề 'main' hoặc bởi một số chủ đề khác. –
hoạt động trên vs2013? –