2013-03-05 28 views
7

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); 
} 
+1

bản sao có thể có của http://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads – engineerC

+3

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. –

+0

hoạt động trên vs2013? –

Trả lời

0

Xin lỗi vì đây không phải là câu trả lời trực tiếp cho câu hỏi của bạn, nhưng cũng có thể hữu ích.

Nếu tôi phát hiện lỗi thời gian chạy trong một chuỗi bằng cách bắt ngoại lệ, kiểm tra mã trả về, v.v, tôi có chuỗi đó đóng băng toàn bộ quá trình. Tôi cũng sẽ có nó tắt ftracing (một bản sao Linux của dtrace) để bất kỳ bản ghi theo dõi tôi có thể nhận được được bảo tồn cho dẫn đến vấn đề. Tôi sợ tôi không biết tương đương với Windows là gì. Sau đó tôi có thể đính kèm một trình gỡ lỗi và xem xét những gì đang xảy ra, thậm chí có thể sửa một giá trị và thực hiện.

Nó không hữu ích trong mã được triển khai nhưng nó rất tuyệt trong quá trình phát triển. Cái nhìn có vấn đề là tốt bởi vì mọi thứ đều có 'như là', không có thư giãn, các chủ đề khác không có nhiều cơ hội để đi đến đâu, v.v. Điều đó có thể giúp xác định lỗi dễ dàng hơn. Đối với mã được triển khai, tôi có thể kích hoạt một kết xuất lõi (tôi có xu hướng chạy trên một cái gì đó unixy) thay thế. Rõ ràng đó là không tốt nếu một số mức độ làm sạch là cần thiết.

Các vấn đề liên quan