관찰자 패턴의 스레드 안전 구현을 찾고있었습니다. https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html 를 읽고 “바퀴를 재발 명하지 말고 대신 Boost.Signals2를 사용하십시오”라는 점 4에 대해 생각했습니다. . 그래서 다음 코드를 시도하고 다중 스레드 응용 프로그램에서 사용하는 것이 안전한지 묻고 싶었습니다. 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(); }
Answer
Boost.Signals2는 스레드입니다. -safe 라이브러리. 내부적으로 뮤텍스 잠금을 사용합니다. 이 도움말 에 설명 된대로 몇 가지주의 사항이 있습니다.
Boost.Signals2에서 제공하는 거의 모든 클래스는 스레드로부터 안전하며 다중 스레드 응용 프로그램에서 사용할 수 있습니다. 예를 들어
boost::signals2::signal
및 는 다른 스레드에서 액세스 할 수 있습니다.반면에
boost::signals2::shared_connection_block
는 스레드로부터 안전하지 않습니다. 여러 개체가 있기 때문에이 제한은 중요하지 않습니다. 영형 f 유형boost::signals2::shared_connection_block
는 다른 스레드에서 생성 될 수 있으며 동일한 연결 객체를 사용할 수 있습니다.
그러나 가장 간단한 기본 형식 인 Boost.Signals2는 멀티 스레딩에 안전합니다.
당신이 제시 한 예제는 실제로 스레드로부터 안전합니다.
notifyObservers 중에 Observer가 파괴되면 어떻게 되나요?
슬롯이 선제 적으로 연결 해제됩니다.