C ++ waarnemerpatroon via boost.signals2

Ik was op zoek naar een threadveilige implementatie van het waarnemerpatroon. Ik las https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html en dacht aan punt 4 “Vind het wiel niet opnieuw uit, gebruik in plaats daarvan Boost.Signals2” . Dus ik probeerde de volgende code en wilde vragen of het veilig is om te worden gebruikt in een multithread-applicatie? Wat gebeurt er als een Observer wordt vernietigd tijdens 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(); } 

Antwoord

Boost.Signals2 is een thread -veilige bibliotheek. Het gebruikt intern mutex-vergrendeling. Er zijn enkele kanttekeningen, zoals uitgelegd in dit artikel :

Bijna alle klassen die door Boost.Signals2 worden geleverd, zijn thread-safe en kunnen worden gebruikt in toepassingen met meerdere threads. Objecten van het type boost::signals2::signal en boost::signals2::connection is toegankelijk via verschillende threads.

Aan de andere kant is boost::signals2::shared_connection_block niet thread-safe. Deze beperking is niet belangrijk omdat meerdere objecten O f type boost::signals2::shared_connection_block kan in verschillende threads worden gemaakt en kan hetzelfde verbindingsobject gebruiken.

maar in zijn Eenvoudigste en standaardformulieren, Boost.Signals2 is veilig voor multi-threading.

Uw gegeven voorbeeld is inderdaad thread-safe.

Wat gebeurt er als een waarnemer wordt vernietigd tijdens notificatieObservers?

De verbinding met de sleuf wordt preventief verbroken.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *