Estaba buscando una implementación segura de subprocesos del patrón de observador. Leí https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html y estaba pensando en el punto 4 «No reinventes la rueda, usa Boost.Signals2 en su lugar» . Entonces probé el siguiente código y quería preguntar si es seguro usarlo en una aplicación multiproceso. ¿Qué sucede si un Observer
se destruye durante 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(); }
Respuesta
Boost.Signals2 es un hilo -Biblioteca segura. Utiliza bloqueo mutex internamente. Hay algunas advertencias, como se explica en este artículo :
Casi todas las clases proporcionadas por Boost.Signals2 son seguras para subprocesos y pueden usarse en aplicaciones multiproceso. Por ejemplo, objetos de tipo
boost::signals2::signal
y desde diferentes subprocesos.Por otro lado,
boost::signals2::shared_connection_block
no es seguro para subprocesos. Esta limitación no es importante porque varios objetos o f typeboost::signals2::shared_connection_block
se puede crear en diferentes subprocesos y puede usar el mismo objeto de conexión.
pero en su formas más simples y predeterminadas, Boost.Signals2 es seguro para múltiples subprocesos.
Su ejemplo dado es, de hecho, seguro para subprocesos.
¿Qué sucede si un Observer se destruye durante notifyObservers?
La ranura se desconecta de forma preventiva.