A megfigyelő minta szálbiztos megvalósítását kerestem. Olvastam a következőt: https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html , és arra gondoltam, hogy a 4. pont “Ne keresse újra a kereket, inkább használja a Boost.Signals2-t” . Tehát kipróbáltam a következő kódot, és azt akartam kérdezni, hogy biztonságos-e a többszálas alkalmazásban való használat? Mi történik, ha Observer
tönkremegy notifyObservers
?
#include <boost/signals2.hpp> #include <iostream> #include <string> class AbstractObserver { public: using SignalType = boost::signals2::signal<void()>; virtual ~AbstractObserver() = default; virtual void notify() = 0; void registerAtSubject(SignalType &sig) { connection_ = sig.connect([this]() { notify(); }); } private: boost::signals2::scoped_connection connection_; }; class Subject { AbstractObserver::SignalType sig_; public: void registerObserver(AbstractObserver &observer) { observer.registerAtSubject(sig_); } void notifyObservers() const { sig_(); } }; class Observer : public AbstractObserver { std::string id_; public: explicit Observer(std::string id) : id_(std::move(id)) {}; void notify() override { std::cout << "Observer " << id_ << " got notified" << std::endl; } }; int main() { Subject c; { Observer o2("B"); { Observer o1("A"); c.registerObserver(o1); c.notifyObservers(); c.registerObserver(o2); c.notifyObservers(); } c.notifyObservers(); } c.notifyObservers(); }
Válasz
A Boost.Signals2 egy szál -safe könyvtár. Belsőleg használja a mutex zárolást. Van néhány figyelmeztetés, amint azt a ebben a cikkben leírják:
A Boost.Signals2 szinte minden osztálya szálbiztos és többszálas alkalmazásokban használható. Például a
boost::signals2::signal
és különböző szálakból érhető el.Másrészt a
boost::signals2::shared_connection_block
nem biztonságos a szálak számára. Ez a korlátozás nem fontos, mert több objektum o Az f típusboost::signals2::shared_connection_block
különböző szálakban hozható létre, és ugyanazt a kapcsolati objektumot használhatja.
de annak a legegyszerűbb és alapértelmezett űrlap, a Boost.Signals2 többszálas biztonságos.
A megadott példa valóban szálbiztos.
Mi történik, ha egy megfigyelőt megsemmisítenek az értesítési megfigyelők?
A nyílást megelőzően leválasztják.