boost.signals2を介したC ++オブザーバーパターン

オブザーバーパターンのスレッドセーフな実装を探していました。 https://xinhuang.github.io/posts/2015-02-11-how-a-multi-threaded-implementation-of-the-observer-pattern-can-fail.html を読み、ポイント4「車輪の再発明ではなく、代わりにBoost.Signals2を使用する」について考えていました。 。そこで、次のコードを試し、マルチスレッドアプリケーションで安全に使用できるかどうかを確認したいと思いました。ObservernotifyObservers

#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(); } 

回答

Boost.Signals2はスレッドです-安全なライブラリ。内部でミューテックスロックを使用します。この記事で説明されているように、いくつかの注意点があります:

Boost.Signals2によって提供されるほとんどすべてのクラスはスレッドセーフであり、マルチスレッドアプリケーションで使用できます。たとえば、タイプboost::signals2::signalおよびboost::signals2::connectionにはさまざまなスレッドからアクセスできます。

一方、boost::signals2::shared_connection_blockはスレッドセーフではありません。複数のオブジェクトがあるため、この制限は重要ではありません。 oo fタイプboost::signals2::shared_connection_blockは、異なるスレッドで作成でき、同じ接続オブジェクトを使用できます。

最も単純でデフォルトの形式であるBoost.Signals2は、マルチスレッドセーフです。

与えられた例は、確かにスレッドセーフです。

notifyObservers中にオブザーバーが破棄された場合はどうなりますか?

スロットはプリエンプティブに切断されます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です