这是一个简化的观察者模式:
要实现它,诀窍是观察者应该 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_)
.所以这里是我的问题:最佳答案
您有 undefined bahavior当一个线程读取共享指针时 g_profile
(观察者)而另一个线程写入它(当创建者调用 std::shared_ptr::reset
时)
如果您想使用 shared_ptr
从两个线程你必须使用锁或 atomic_shared_ptr
.
还有 volatile
不保证任何同步,因为它在 java 中。见 this answer .
关于c++ - 使用 std::shared_ptr/weak_ptr 简化观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63025270/