【アールシーユー】

RCU(Read-Copy-Update) とは?

公開:
💡 新しい版へ切り替えても、読んでいる人の古い版は残す

読者が使っているデータを直ちに破棄せず、参照の切り替えと古いデータの回収を分ける同期方式。読み取りが多い共有データに適している。

📌 このページのポイント
公開の切り替えと、古い版の回収を分ける 古い読者 旧版を参照中 古い読者 読み取りを終了 更新者 新版へ切り替え 猶予期間 既存の読者を待つ 回収 旧版を解放 新しく始まる読者は、新しい参照を取得できる
猶予期間は固定の待ち時間ではない。図はコピーして置き換える典型例。
ひよこ ひよこ
書き換える人が来ても、読み続けられるの?
ペンギン先生 ペンギン先生
RCUではそうできる形にデータを管理するよ。典型例では新しい版を用意し、共有ポインタを切り替える。すでに古い版を読んでいた人のために、その版はまだ残しておくんだ。読む人が多く、更新が少ない場面で役立つね。
ひよこ ひよこ
古い版はいつ片づけるの?
ペンギン先生 ペンギン先生
切り替え前からの読み取り区間がすべて終わったと確認できたあとだよ。この確認のための期間を猶予期間、grace periodと呼ぶんだ。一定の秒数だけ待てばよいわけでも、将来始まる読者まで全員いなくなるのを待つわけでもないよ。
ひよこ ひよこ
コピーしてポインタを書き換えるだけでいい?
ペンギン先生 ペンギン先生
それだけでは不十分だよ。Linuxではrcu_assign_pointerで公開し、読む側はRCU読み取り区間内でrcu_dereferenceなどを使う。初期化した中身が適切に見える順序と、読んでいる間に回収されないことの両方が必要なんだ。
ひよこ ひよこ
更新する人が二人いたら?
ペンギン先生 ペンギン先生
RCUだけで更新者同士の競合がなくなるわけではないよ。別のロックなどで更新を調整する必要がある。また、読み取り区間を出たあとも古い参照を使うなら、参照カウントなど追加の保護が必要だね。RCUの規則を守って初めて安全になるんだ。
もっと詳しく知りたい人へ

毎回データ全体をコピーする方式ですか?

いいえ。コピーして置き換えるのは代表的な使い方です。リストから要素を外す処理などでも、取り外しと回収を分離する考え方を使えます。読み取り中のオブジェクトの内容を無条件に変更してよいという意味ではありません。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「RCU(Read-Copy-Update)」って出てきたら「読者を守りながら、古いデータの回収を後へ延ばす同期」と思えればだいたいOK!

参考資料

← 用語集にもどる