2

我在我的应用程序中使用 boost 库进行线程和同步。

首先,我必须说同步线程中的异常对我来说是新事物。无论如何,下面是我想要实现的伪代码。我希望同步线程抛出与执行通知的线程可能抛出的相同异常。我怎样才能做到这一点?

无法从 Stack Overflow 中找到有关使用 boost 线程模型的跨线程交互引发异常的任何主题

提前谢谢了!

// mutex and scondition variable for the problem
mutable boost::mutex conditionMutex;
mutable boost::condition_variable condition;

inline void doTheThing() const {

   if (noone doing the thing) {
      try {
          doIt()
          // I succeeded
          failed = false;
          condition.notify_all();
      }
      catch (...) {
          // I failed to do it
          failed = true;
          condition.notify_all();
          throw
      }
  else {
      boost::mutex::scoped_lock lock(conditionMutex);
      condition.wait(lock);
      if (failed) {
          // throw the same exception that was thrown from 
          // thread doing notify_all
       }
  }

}

4

1 回答 1

1

因此,您希望第一个命中的线程doTheThing()call doIt(),以及命中的所有后续线程doTheThing()等待第一个线程完成调用doIt(),然后再继续。

我认为这应该可以解决问题:

boost::mutex conditionMutex; // mutable qualifier not needed
bool failed = false;
bool done = false;

inline void doTheThing() const {

   boost::unique_lock uql(conditionMutex);

   if (!done) {
       done = true;
       try {
           doIt();
           failed = false;
       }
       catch (...) {
           failed = true;
           throw
       }
   }
   else if (failed)
   {
       uql.unlock();
       // now this thread knows that another thread called doIt() and an exception 
       // was thrown in that thread.
   }

}

重要笔记:

每个调用的线程都doTheThing()必须锁定。没有办法解决这个问题。您正在同步线程,并且一个线程要知道另一个线程中发生的任何事情,它必须锁定。(或者它可以使用原子内存操作,但这是一种更高级的技术。)变量faileddoneconditionMutex.

uql当函数正常退出抛出异常时, C++ 将调用析构函数。

编辑哦,至于向所有其他线程抛出异常,忘记这一点,这几乎是不可能的,而且这不是在 C++ 中完成的方式。相反,每个线程都可以检查第一个线程是否doIt()在我上面指出的位置成功调用。

编辑没有语言支持将异常传播到另一个线程。您可以将异常传播到另一个线程的问题概括为将消息传递到另一个线程对于线程之间传递消息的问题( boost::asio::io_service::post() )有很多库解决方案,您可以传递包含异常的消息,并说明在收到消息时抛出该异常. 不过,这是个坏主意。仅当您遇到阻止您通过普通函数返回展开调用堆栈的错误时才抛出异常。这就是一个例外——当以通常的方式返回时,从函数返回的另一种方式是没有意义的。

于 2011-11-14T18:24:55.610 回答