0

我正在开发一个 C++ 程序,它有一个“扫描”方法,它将触发一个运行相对较长的扫描过程。当该过程完成时,scan 方法将使用观察者模式通知观察者结果。

我想为每次扫描创建一个单独的线程。这样我可以同时运行多个扫描。当每个扫描过程完成时,我希望 scan 方法通知侦听器。

根据 boost 线程库,看起来我可以做这样的事情:

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

boost::mutex io_mutex;

void scan(int scan_target, vector<Listener> listeners)  
{
  //...run scan 
  {
    boost::mutex::scoped_lock  
      lock(io_mutex);
    std::cout << "finished scan" << endl;
    // notify listeners by iterating through the vector
    // and calling "notify()

  }
}

int main(int argc, char* argv[])
{

  vector<Listener> listeners
  // create 
  boost::thread thrd1(
    boost::bind(&scan, 1, listeners));
  boost::thread thrd2(
    boost::bind(&scan, 2, listeners));
  //thrd1.join();
  //thrd2.join();
  return 0;
} 

这看起来大致正确吗?我是否需要对侦听器的呼叫进行互斥?可以摆脱连接吗?

4

3 回答 3

1

您是否需要锁定取决于您对通知的处理方式。我认为,如果您只将锁放在需要单线程访问的那些侦听器的通知功能中,那会更合适。

于 2009-04-28T03:42:31.647 回答
0

您的 Listener::Notify() 正在从多个线程中调用,因此除非 Notify() 没有副作用,否则您必须执行以下三个操作之一:

  1. 外部锁(您的示例):在调用 Listener::Notify() 之前获取互斥锁
  2. 内部锁:Listener::Notify() 将在内部获取锁
  3. 无锁:在谷歌搜索“无锁算法”

每个选项都有优点/缺点...

对于(我认为)你需要的东西,选项 1 会很好。

而且,您必须保留连接语句,否则您的 main() 可能会在您的线程完成工作之前退出。还可以考虑使用boost::thread_pooland joint_all

于 2009-04-28T04:18:32.763 回答
0

我不知道提升的东西,但从概念上看它看起来是正确的。您有想要收到状态更改通知的观察者。当“合格事件”发生时,您必须遍历观察者列表(或向量,类似的东西)来通知。您还想以某种方式确保并发通知不会给您带来麻烦,

(这是关于该模式的Wikipedia 文章。)

于 2009-04-28T03:07:05.570 回答