2009-09-03 18 views
5

Czy ktoś może pokazać prosty, ale pełny przykład, w jaki sposób można użyć biblioteki wyjątków Boost do przenoszenia wyjątków między wątkami, modyfikując poniższy kod?C++ Boost Code przykład rzucania wyjątku między wątkami

To, co implementuję, to prosty wielowątkowy wzorzec delegata.

class DelegeeThread 
{ 
public: 
    void operator()() 
    { 
    while(true) 
    { 
     // Do some work 

     if(error) 
     { 
     // This exception must be caught by DelegatorThread 
     throw std::exception("An error happened!"); 
     } 
    } 
    } 
}; 

class DelegatorThread 
{ 
public: 
    DelegatorThread() : delegeeThread(DelegeeThread()){} // launches DelegeeThread 
    void operator()() 
    { 
    while(true) 
    { 
     // Do some work and wait 

     // ? What do I put in here to catch the exception thrown by DelegeeThread ? 
    } 
    } 
private: 
    tbb::tbb_thread delegeeThread; 
}; 
+0

wow ... 10 godzin po poście, a nikt nie udzielił odpowiedzi? czy źle wyraziłem moje pytanie, czy ten problem jest trudny? – sivabudh

+1

Pamiętam, że cokolwiek kończy się wdrażaniem, może nie być tym, czego oczekujesz. kiedy DelegeeThread chce wywołać wyjątek w innym wątku, Delegujący prawdopodobnie wykona jakąś niepowiązaną pracę lub może już zakończyć działanie, więc wstrzymanie może być opóźnione lub wcale się nie zdarzyć. – asveikau

+0

Oczywiście, o czym wspomniałeś, zgadzam się. – sivabudh

Odpowiedz

4

Założono, że chcesz, aby delegat był wykonywany asynchronicznie w oddzielnym wątku. Oto przykład użycia wątków wspomagających i wyjątków:

#include <boost/exception/all.hpp> 
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
#include <iostream> 

class DelegeeThread 
{ 
public: 
    void operator()(boost::exception_ptr& excPtr) 
    { 
     try 
     { 
      int counter = 0; 
      while(true) 
      { 
       // Do some work 

       if(++counter == 1000000000) 
       { 
        throw boost::enable_current_exception(std::exception("An error happened!")); 
       } 

      } 
     } 
     catch(...) 
     { 
      // type of exception is preserved 
      excPtr = boost::current_exception(); 
     } 
    } 
}; 

class DelegatorThread 
{ 
public: 
    DelegatorThread() : 
     delegeeThread(boost::bind(&DelegeeThread::operator(), boost::ref(delegee), boost::ref(exceptionPtr))) 
     { 
      // launches DelegeeThread 
     } 

    void wait() 
    { 
     // wait for a worker thread to finish 
     delegeeThread.join(); 

     // Check if a worker threw 
     if(exceptionPtr) 
     { 
      // if so, rethrow on the wait() caller thread 
      boost::rethrow_exception(exceptionPtr); 
     } 
    } 

private: 
    DelegeeThread   delegee; 
    boost::thread   delegeeThread; 
    boost::exception_ptr exceptionPtr; 
}; 


int main() 
{ 
    try 
    { 
     // asynchronous work starts here 
     DelegatorThread dt; 

     // do some other work on a main thread... 

     dt.wait(); 

    } 
    catch(std::exception& e) 
    { 
     std::cout << e.what(); 
    } 

    system("pause"); 
    return 0; 
} 
+0

Dzięki. Świetna odpowiedź. – sivabudh

2

Możesz użyć Boost :: Exception, aby rozwiązać ten problem. Oto przykład użycia ich wyjątków lib do uzyskania wyjątku w wątku wywołującym: http://www.boost.org/doc/libs/1_40_0/libs/exception/doc/tutorial_exception_ptr.html

Jeśli dobrze pamiętam, C++ 0x zapewni mechanizm pozwalający na coś podobnego do rozwiązania tego konkretnego problemu.

+0

tak, zgadzam się, że musimy użyć Boost :: Exception. Już patrzę na przykład, ale tak naprawdę nie wiem jak go użyć. – sivabudh

Powiązane problemy