答案:通过线程或任务队列实现异步通知,确保线程安全与资源释放;具体采用std::async、线程池或工作队列优化性能。

在C++中实现观察者模式的异步通知,关键在于将观察者的更新操作从主线程中解耦,通过线程或事件队列机制进行非阻塞调用。这样可以避免被观察者因等待所有观察者处理完成而阻塞。
观察者模式基础结构
先定义基本的抽象接口:
class Observer {
public:
virtual ~Observer() = default;
virtual void update(int message) = 0;
};
<p>class Subject {
public:
virtual ~Subject() = default;
virtual void attach(Observer<em> obs) = 0;
virtual void detach(Observer</em> obs) = 0;
virtual void notify(int message) = 0;
};</p>使用线程实现异步通知
最直接的方式是每次通知时启动一个线程(或使用线程池)来调用观察者的update方法。
#include <vector>
#include <thread>
#include <mutex>
<p>class AsyncSubject : public Subject {
private:
std::vector<Observer*> observers;
mutable std::mutex mtx;</p><p>public:
void attach(Observer* obs) override {
std::lock_guard<std::mutex> lock(mtx);
observers.push_back(obs);
}</p><pre class='brush:php;toolbar:false;'>void detach(Observer* obs) override {
std::lock_guard<std::mutex> lock(mtx);
observers.erase(
std::remove(observers.begin(), observers.end(), obs),
observers.end()
);
}
void notify(int message) override {
std::lock_guard<std::mutex> lock(mtx);
for (auto* obs : observers) {
// 每个观察者在独立线程中处理
std::thread([obs, message]() {
obs->update(message);
}).detach(); // 自动回收资源
}
}};
立即学习“C++免费学习笔记(深入)”;
注意:频繁创建线程开销大,适合低频通知场景。高频场景建议使用线程池。
使用任务队列+工作线程优化
更高效的做法是维护一个共享的任务队列和一组工作线程,避免频繁创建线程。
- 启动一个或多个工作线程监听任务队列
- notify时不创建线程,而是将“调用update”任务推入队列
- 工作线程取出任务并执行
这种方式能更好控制并发数,减少系统开销。
结合std::async简化异步调用
使用
std::async让标准库管理线程调度:
void notify(int message) override {
std::lock_guard<std::mutex> lock(mtx);
for (auto* obs : observers) {
std::async(std::launch::async, [obs, message] {
obs->update(message);
});
}
}
优点:代码简洁,自动管理资源;缺点:无法控制并发数量,可能创建过多线程。
基本上就这些。根据性能要求选择合适方式:轻量级用
std::async,高并发用线程池+队列,简单场景可直接detach线程。关键是保证线程安全和资源释放。










