Stack Overflow Asked by fatun on November 17, 2021
Here is a simplified observer pattern:
To implement it, the trick is that observers shall refcnt profile, so the last observer (or creator) can safely destroy it.
I can do it without shared_ptr/weak_ptr, but I wonder if using them can avoid re-inventing wheels.
Here is my code:
#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
}
But the program crashes either at
std::weak_ptr<Profile> weak = g_profile
or assert(a == prof->a_)
. So here are my questions:
You have undefined bahavior when one thread reads from the shared pointer g_profile
(observer) while the other thread writes to it (when creator calls std::shared_ptr::reset
)
If you want to use the shared_ptr
from two threads you'll have to use a lock or atomic_shared_ptr
.
Also volatile
does not guarantee any synchronization as it does in java. See this answer.
Answered by Mike van Dyke on November 17, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP