观察者模式的线程实现 - C ++

时间:2009-04-28 02:37:34

标签: c++ multithreading boost observer-pattern

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

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

根据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;
} 

这看起来大致正确吗?我是否需要将呼叫固定为听众?可以摆脱连接吗?

3 个答案:

答案 0 :(得分:1)

是否需要锁定取决于您对通知的处理方式。我认为如果你把锁只放在需要单线程访问的那些监听器的notify函数中会更容易。

答案 1 :(得分:0)

我不知道增强的东西,但从概念上看它看起来是正确的。您有观察员希望收到状态变化的通知。当发生“合格事件”时,您必须通过观察者的列表(或类似的向量)来通知。您还想确保并发通知不会给您带来麻烦,

(这是模式上的Wikipedia articl e。)

答案 2 :(得分:0)

您的侦听器:: Notify()是从多个线程调用的,因此除非Notify()没有副作用,否则您必须执行以下三个中的一个:

  1. 外部锁定(您的示例):在调用Listener :: Notify()
  2. 之前获取互斥锁
  3. 内部锁定:Listener :: Notify()将在内部获取锁定
  4. 免费锁定:在Google中搜索“锁定免费算法”
  5. 每个选项都有优点/缺点......

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

    并且,您必须保留join语句,否则您的main()可能会在您的线程完成其工作之前退出。另请考虑使用boost::thread_pooljoint_all

相关问题