[英]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.