2009-09-03 8 views
5

Qualcuno può mostrare un semplice ma completo esempio di come utilizzare la libreria di eccezioni Boost per trasferire le eccezioni tra thread modificando il codice seguente?Esempio di codice C++ Boost di lancio di un'eccezione tra i thread

Quello che sto implementando è un semplice pattern Delegate multi-thread.

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 ore dopo il post, e nessuno ha dato una risposta? ho pronunciato male la mia domanda, o questo problema è difficile? – sivabudh

+1

Vorrei ricordare che qualunque cosa tu finisca per implementare potrebbe non essere quello che ti aspetti. quando DelegeeThread vuole attivare un'eccezione nell'altro thread, il Delegator eseguirà probabilmente del lavoro non correlato o potrebbe essere già terminato, quindi il problema potrebbe essere ritardato o non avvenire affatto. – asveikau

+0

sicuro, il punto che hai citato, sono d'accordo. – sivabudh

risposta

4

Presumo che si desideri eseguire il delegato in modo asincrono su un thread separato. Ecco l'esempio usando boost threads ed eccezioni:

#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

Grazie. Bella risposta. – sivabudh

2

È possibile utilizzare Boost :: Exception per risolvere questo problema. Ecco un esempio di come utilizzare la loro eccezione lib per ottenere l'eccezione nel thread chiamante: http://www.boost.org/doc/libs/1_40_0/libs/exception/doc/tutorial_exception_ptr.html

Se ricordo bene, C++ 0x fornirà un meccanismo per consentire qualcosa di simile a risolvere questo particolare problema.

+0

sì, sono d'accordo che dobbiamo usare Boost :: Exception. Ho già visto un esempio, ma non ho davvero capito come usarlo. – sivabudh