Wzorzec obserwatora C ++ za pośrednictwem boost.signals2

Szukałem bezpiecznej wątkowo implementacji wzorca obserwatora. Czytałem https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html i zastanawiałem się nad punktem 4 „Nie”, aby wymyślać koło na nowo, zamiast tego użyj Boost.Signals2 . Wypróbowałem więc poniższy kod i chciałem zapytać, czy można go bezpiecznie używać w aplikacji wielowątkowej? Co się stanie, jeśli Observer zostanie zniszczony podczas 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(); } 

Odpowiedź

Boost.Signals2 to wątek -bezpieczna biblioteka. Wewnętrznie korzysta z blokowania mutexów. Istnieją pewne zastrzeżenia, zgodnie z opisem w tym artykule :

Prawie wszystkie klasy dostarczane przez Boost.Signals2 są bezpieczne dla wątków i mogą być używane w aplikacjach wielowątkowych. Na przykład obiekty typu boost::signals2::signal i boost::signals2::connection można uzyskać z różnych wątków.

Z drugiej strony boost::signals2::shared_connection_block nie jest bezpieczny dla wątków. To ograniczenie nie jest ważne, ponieważ wiele obiektów o typ f boost::signals2::shared_connection_block można tworzyć w różnych wątkach i używać tego samego obiektu połączenia.

ale w jego Najprostsze i domyślne formularze, Boost.Signals2 jest bezpieczna dla wielowątkowości.

Podany przykład jest rzeczywiście bezpieczny dla wątków.

Co się stanie, jeśli Observer zostanie zniszczony podczas notifyObservers?

Slot zostanie odłączony zapobiegawczo.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *