【问题标题】:C++ Boost Code example of throwing an exception between threads线程间抛出异常的 C++ Boost 代码示例
【发布时间】:2010-11-25 08:22:28
【问题描述】:

有人可以展示一个简单但完整的示例,说明如何通过修改下面的代码来使用 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;
};

【问题讨论】:

  • 哇...发布后 10 小时,没有人给出答案?我的问题用词不当,还是这个问题很难?
  • 我会记住,无论您最终实施什么,都可能不是您所期望的。当 DelegeeThread 想要在另一个线程中触发异常时,Delegator 可能正在做一些不相关的工作或者可能已经终止,因此捕获可能会延迟或根本不发生。
  • 当然,你提到的这一点,我同意。

标签: c++ multithreading exception boost


【解决方案1】:

我假设您希望委托在单独的线程上异步执行。以下是使用 boost 线程和异常的示例:

#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;
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 是的,我同意我们需要使用 Boost::Exception。我已经看过一个示例,但我并没有真正了解如何使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 2012-11-28
    相关资源
    最近更新 更多