C ++ vzor pozorovatele prostřednictvím boost.signals2

Hledal jsem implementaci vzoru pozorovatele bezpečnou pro vlákna. Přečetl jsem https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html a přemýšlel jsem nad bodem 4 „Neobjevujte znovu kolo, místo toho použijte Boost.Signals2“ . Takže jsem zkusil následující kód a chtěl jsem se zeptat, jestli je bezpečné ho použít v aplikaci s více vlákny? Co se stane, když je Observer zničen během 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(); } 

Odpověď

Boost.Signals2 je vlákno -safe knihovna. Používá interně zamykání mutexu. Existují některá upozornění, jak je vysvětleno v tomto článku :

Téměř všechny třídy poskytované Boost.Signals2 jsou bezpečné pro vlákna a lze je použít v aplikacích s více vlákny. Například objekty typu boost::signals2::signal a boost::signals2::connection lze přistupovat z různých vláken.

Na druhou stranu boost::signals2::shared_connection_block není bezpečné pro vlákna. Toto omezení není důležité, protože více objektů Ó f type boost::signals2::shared_connection_block lze vytvořit v různých vláknech a lze použít stejný objekt připojení.

, ale v jeho nejjednodušší a výchozí formuláře, Boost.Signals2 je bezpečný pro více vláken.

Váš uvedený příklad je skutečně bezpečný pro vlákna.

Co se stane, pokud je pozorovatel zničen během notifyObservers?

Slot je preventivně odpojen.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *