【发布时间】:2020-07-22 01:09:19
【问题描述】:
这是一个简化的观察者模式:
- 创建者在启动时创建配置文件,并在完成时“销毁”它。
- 零,一个或多个观察者随时尝试“查看”配置文件。
要实现它,诀窍是观察者应该 refcnt 配置文件,因此最后一个观察者(或创建者)可以安全地销毁它。
不用shared_ptr/weak_ptr我也能做到,但我想知道使用它们是否可以避免重新发明轮子。
这是我的代码:
#include <iostream>
#include <memory>
#include <thread>
#include <cassert>
volatile bool playing = true;
class Profile {
public:
int a_;
Profile(int v) {a_ = v;}
};
std::shared_ptr<Profile> g_profile{ nullptr };
void observer() {
do {
// observe profile if I can
std::weak_ptr<Profile> weak = g_profile;
if (auto prof = weak.lock()) {
auto a = prof->a_;
// if prof is stable, I shall see the same a_
assert(a == prof->a_);
}
else {
std::cout << ".";
}
} while (playing);
}
void creator() {
do {
// create profile when I start
g_profile.reset(new Profile(std::rand()));
std::weak_ptr<Profile> weak = g_profile;
assert(weak.lock() != nullptr);
// doing some work ...
// destroy profile when I am done
g_profile.reset();
} while (playing);
}
void timer() {
std::this_thread::sleep_for(std::chrono::seconds(10));
playing = false;
}
int main() {
std::thread cr{ creator };
std::thread ob{ observer };
std::thread tm{ timer };
cr.join();ob.join();tm.join();
// no memory leak
}
但程序崩溃要么在
std::weak_ptr<Profile> weak = g_profile 或 assert(a == prof->a_)。所以这是我的问题:
- 您是否有使用 shared_ptr/weak_ptr 实现观察者模式(或变体)的指针?
- 上面的代码有什么问题?你能做对吗?
【问题讨论】:
标签: c++ concurrency