Motif dobservateur C ++ via boost.signals2

Je cherchais une implémentation thread-safe du motif dobservateur. Jai lu https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html et je pensais au point 4 « Ne réinventez pas la roue, utilisez plutôt Boost.Signals2 » . Jai donc essayé le code suivant et je voulais demander sil pouvait être utilisé en toute sécurité dans une application multithread? Que se passe-t-il si un Observer est détruit pendant 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(); } 

Réponse

Boost.Signals2 est un fil de discussion -safe. Elle utilise le verrouillage mutex en interne. Il y a quelques mises en garde, comme expliqué dans cet article :

Presque toutes les classes fournies par Boost.Signals2 sont thread-safe et peuvent être utilisées dans des applications multithread. Par exemple, les objets de type boost::signals2::signal et boost::signals2::connection est accessible à partir de différents threads.

Dun autre côté, boost::signals2::shared_connection_block nest pas thread-safe. Cette limitation nest pas importante car plusieurs objets o f type boost::signals2::shared_connection_block peut être créé dans différents threads et peut utiliser le même objet de connexion.

mais dans son formes les plus simples et par défaut, Boost.Signals2 est sûr pour le multi-threading.

Votre exemple donné est, en effet, thread-safe.

Que se passe-t-il si un observateur est détruit pendant notifyObservers?

Le slot est déconnecté de manière préventive.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *