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

Posted

技术标签:

【中文标题】观察者模式的线程实现 - C++【英文标题】:Threaded implementation of observer pattern - C++ 【发布时间】:2009-04-28 02:37:33 【问题描述】:

我正在开发一个 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;
 

这看起来大致正确吗?我需要互斥对侦听器的调用吗?可以摆脱连接吗?

【问题讨论】:

你想用互斥锁保护什么?听众名单?您是否试图防止列表中的重复迭代? 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

(这是图案上的Wikipedia article。)

【讨论】:

【参考方案3】:

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

    外部锁(您的示例):在调用 Listener::Notify() 之前获取互斥锁 内部锁:Listener::Notify() 将在内部获取锁 无锁:在 google 中搜索“无锁算法”

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

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

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

【讨论】:

以上是关于观察者模式的线程实现 - C++的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之观察者模式C++实现

设计模式之观察者模式C++实现

观察者模式C++实现

C++观察者模式(发布-订阅)的使用

C++观察者模式(发布-订阅)的使用

C++观察者模式(发布-订阅)的使用