2009-09-03 15 views
5

¿Puede alguien mostrar un ejemplo simple pero completo de cómo se podría usar la biblioteca de excepción de Boost para transferir excepciones entre hilos modificando el código a continuación?C++ Boost Code ejemplo de lanzar una excepción entre hilos

Lo que estoy implementando es un patrón simple de delegado de subprocesos múltiples.

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 horas después del mensaje, y nadie respondió? ¿Le dije mal mi pregunta o este problema es difícil? – sivabudh

+1

Me gustaría tener en cuenta que cualquier cosa que termine implementando podría no ser lo que espera. cuando DelegeeThread desea desencadenar una excepción en el otro hilo, el Delegador probablemente realizará un trabajo no relacionado o podría haber finalizado, por lo que la captura podría retrasarse o no ocurrir. – asveikau

+0

seguro, el punto que mencionaste, estoy de acuerdo. – sivabudh

Respuesta

4

Supuse que desea que el delegado se ejecute de forma asincrónica en un hilo separado. Aquí está el ejemplo usando hilos de impulso y excepciones:

#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

Gracias. Gran respuesta. – sivabudh

2

Es posible que desee utilizar Boost :: Exception para resolver este problema. Aquí hay un ejemplo de cómo usar su excepción lib para obtener la excepción en el hilo de llamada: http://www.boost.org/doc/libs/1_40_0/libs/exception/doc/tutorial_exception_ptr.html

Si mal no recuerdo, C++ 0x proporcionará un mecanismo para permitir que algo similar resuelva este problema en particular.

+0

sí, acepto que necesitamos usar Boost :: Exception. Ya he visto un ejemplo, pero realmente no sé cómo usarlo. – sivabudh

Cuestiones relacionadas