[英]simplfied observer pattern with std::shared_ptr/weak_ptr
这是一个简化的观察者模式:
要实现它,诀窍是观察者应该 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_)
处崩溃。 所以这是我的问题:
当一个线程从共享指针g_profile
(观察者)读取而另一个线程写入它时(当创建者调用std::shared_ptr::reset
时),您有未定义的行为
如果要从两个线程中使用shared_ptr
,则必须使用 lock 或atomic_shared_ptr
。
volatile
也不像在 java 中那样保证任何同步。 看到这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.