• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    class template
    <rcu>

    std::rcu_obj_base

    namespace std {
      template<class T, class D = default_delete<T>>
      class rcu_obj_base;
    }
    

    概要

    RCU機構の保護対象とする型の基底クラス。

    使用するときは、Trcu_obj_baseを公開継承した上で派生クラスTrcu_obj_baseのテンプレート引数にする(CRTP)。

    適格要件

    • T不完全型でもよいが、特殊化されたrcu_obj_baseのメンバが参照されるまでに完全型とすること。
    • Dは関数オブジェクト型であり、D型の値dT*型の値ptrに対して式d(ptr)が有効であること。
    • D型は要件 Cpp17DefaultConstructible およ Cpp17MoveAssignable を満たすこと。

    メンバ関数

    名前 説明 対応バージョン
    (constructor) コンストラクタ C++26
    (destructor) デストラクタ C++26
    operator= 代入演算子 C++26
    retire オブジェクト回収をスケジュールする C++26

    #include <atomic>
    #include <mutex>
    #include <thread>
    #include <rcu>
    
    struct Data : std::rcu_obj_base<Data> {
      int m1, m2;
    };
    
    // 共有データを指すポインタ
    std::atomic<Data*> data;
    
    void reader()
    {
      std::scoped_lock slk{std::rcu_default_domain()};
      // 共有データを読み取り(Read)
      Data *p = data;
    
      std::println("{} {}", p->m1, p->m2);
    }
    
    void updater()
    {
      Data *newdata = new Data{1, 2};
      // 新しいデータで共有データを更新(Update)
      Data *old_data = data.exchange(newdata);
    
      // 古いデータを読み取り中のスレッドがなくなったタイミングで
      // データ領域の回収(メモリ解放)を行うようスケジューリングする
      old_data->retire();
    }
    
    int main()
    {
      // 共有データ初期化
      Data *newdata = new Data{0, 0};
      data.store(newdata);
    
      // 共有データへ並行アクセス
      std::jthread th{[] {
        for (int i = 0; i < 3; i++) {
          reader();
        }
      }};
      updater();
    }
    

    出力例

    0 0
    1 2
    1 2
    

    バージョン

    言語

    • C++26

    処理系

    関連項目

    参照