Padrão de observador C ++ via boost.signals2

Eu estava procurando por uma implementação segura de thread do padrão de observador. Eu li https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html e estava pensando no ponto 4 “Não” reinvente a roda, use Boost.Signals2 em vez disso ” . Tentei o seguinte código e queria saber se é seguro ser usado em um aplicativo multithread? O que acontece se um Observer for destruído 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(); } 

Resposta

Boost.Signals2 é um tópico -Biblioteca segura. Ela usa bloqueio mutex internamente. Existem algumas advertências, conforme explicado neste artigo :

Quase todas as classes fornecidas por Boost.Signals2 são thread-safe e podem ser usadas em aplicativos multithread. Por exemplo, objetos do tipo boost::signals2::signal e boost::signals2::connection pode ser acessado de threads diferentes.

Por outro lado, boost::signals2::shared_connection_block não é seguro para threads. Essa limitação não é importante porque vários objetos o f type boost::signals2::shared_connection_block pode ser criado em threads diferentes e pode usar o mesmo objeto de conexão.

mas em seu formulários mais simples e padrão, Boost.Signals2 é seguro para multithreading.

Seu exemplo fornecido é, de fato, thread-safe.

O que acontece se um Observer for destruído durante notificarObservers?

O slot é desconectado preventivamente.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *