Skip to content

Latest commit

 

History

History
118 lines (92 loc) · 2.98 KB

rcu_obj_base.md

File metadata and controls

118 lines (92 loc) · 2.98 KB

rcu_obj_base

  • rcu[meta header]
  • class template[meta id-type]
  • std[meta namespace]
  • cpp26[meta cpp]
namespace std {
  template<class T, class D = default_delete<T>>
  class rcu_obj_base;
}
  • default_delete[link /reference/memory/default_delete.md]

概要

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();
}
  • std::rcu_obj_base[color ff0000]
  • std::rcu_default_domain[link rcu_default_domain.md]
  • retire()[link rcu_obj_base/retire.md]
  • std::scoped_lock[link /reference/mutex/scoped_lock.md]
  • std::jthread[link /reference/thread/jthread.md]
  • exchange[link /reference/atomic/atomic/exchange.md]
  • store[link /reference/atomic/atomic/store.md]

出力例

0 0
1 2
1 2

バージョン

言語

  • C++26

処理系

関連項目

参照