2009-09-03 37 views
5

有人可以通过修改下面的代码来显示一个简单但完整的示例,说明如何使用Boost异常库在线程之间传输异常?C++ Boost代码在线程间抛出异常的示例

我正在实现的是一个简单的多线程委托模式。

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

哇......发帖后10小时,没有人给出答案?我是否严肃地说出我的问题,还是难以解决这个问题? – sivabudh 2009-09-04 02:48:34

+1

我会记住,不管你最终实现的是什么,都可能不是你期望的。当DelegeeThread想要在另一个线程中触发异常时,Delegator可能会做一些不相关的工作或者可能已经终止,因此catch可能会延迟或根本不会发生。 – asveikau 2009-10-08 23:00:23

+0

当然,你提到的观点,我同意。 – sivabudh 2009-10-09 22:41:50

回答

4

我认为你希望委托在一个单独的线程上被异步执行。这里是使用升压线程和例外的例子:

#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

谢谢。很好的答案。 – sivabudh 2011-02-07 02:30:31

2

您可能想要使用Boost :: Exception来解决此问题。这里是一个如何使用异常库来获取调用线程异常的例子:http://www.boost.org/doc/libs/1_40_0/libs/exception/doc/tutorial_exception_ptr.html

如果我记得很清楚,C++ 0x将提供一种机制来允许类似的东西来解决这个特定的问题。

+0

是的,我同意我们需要使用Boost :: Exception。我已经看过一个例子,但我没有真正知道如何使用它。 – sivabudh 2009-09-03 16:50:41