yohhoyの日記

技術的メモをしていきたい日記

synchronic同期プリミティブ

C++1z(C++17)に向けて提案されている同期プリミティブについてメモ。(PDF)N4195 std::synchronic<T> に基づく。初期提案のため概要のみ。

2019-09-12追記:C++2a(C++20)に向けて提案文書 P1135R6 が採択され、atomic変数std::atomic<T>に wait / notify_one / notify_all 操作が追加される。ループ構造と組み合わせることで、N4195 が目指していた効率的な通知/待機機構を実装できる。

std::synchronic<T>クラステンプレートは、スレッド間同期オブジェクトの待機処理を効率的に実装するための低レイヤ同期プリミティブ。atomic変数(std::atomic<T>)のコンセプトを機能拡張し、条件変数(condition variable)のような条件待機/通知機能を追加したもの。*1

  • store 操作は、synchronic オブジェクト(≒atomic変数)への値代入に加えて、同オブジェクト上で待機しているスレッドへのブロック解除通知を行う。
  • 条件付き load 操作 load_when_not_equal, load_when_equal や条件付き待機操作 expect_update は、同 synchronic オブジェクト(≒atomic変数)の値が特定条件を満たすまで呼び出しスレッドをブロックして待機する。
  • Linuxfutexシステムコールや、Windows APIWaitOnAddress/WakeByAddressXxx(Windows 8以降)に相当する。
// C++11 std::atomic<T>
std::atomic<bool> flag;
// 非効率なbusy-wait処理
while (flag.load())
  ;
assert(flag.load() == false);
// N4195 std::synchronic<T>
std::synchronic<bool> flag;
// 効率的なwait処理
flag.expect_update(true);
assert(flag.load() == false);

関連URL

*1:オプションで notify_hint による通知先スレッドの制御(one/all/none)や、expect_hint による待機解除ポリシー(urgent/lazy)も指定可能としている。