【どくしゃかきてもんだい】

読者-書き手問題 とは?

最終更新:
💡 一緒に読める。書き換える間は独占する

共有データへの並行アクセスを、複数の読み手には同時に許し、書き手には他の読み手・書き手から排他的に許す問題。待ち順や飢餓の防止も考える。

📌 このページのポイント
読み取り中と書き込み中は別の状態 ① 読み手が利用中:書き手は待つ 👤 読み手A 読み取り中 👤 読み手B 読み取り中 📄 共有 データ 書き手 待機 ② 書き手が利用中:他の処理は待つ ✏ 書き手A 書き込み中 📄 共有 データ 読み手/ 他の書き手 待機 読み手優先・書き手優先・公平方式などがある 待ち順・飢餓の防止・性能は実装ごとに確認
上段は複数の読み手がアクセス、下段は書き手一人がアクセスする別の時点。実線矢印はアクセスの要求方向で、データの流れる方向ではない。待機者からアクセス矢印は出さない。
ひよこ ひよこ
読者-書き手問題って何?
ペンギン先生 ペンギン先生
共有データを複数の処理が使うときの話だよ。読むだけなら一緒に使えるけど、書き換えるときは一つの処理が独占する。このルールで、途中の変更を他の処理が読んでしまうことなどを防ぐんだ
ひよこ ひよこ
書き手が一人なら、読み手は同時に入れる?
ペンギン先生 ペンギン先生
基本のルールでは入れないよ。読み手同士の同時アクセスは許すけど、書き手のアクセス中は他の読み手も書き手も待つ。図の二つの状態は、別の時点を表しているんだ
ひよこ ひよこ
全部を排他ロックにするより速いの?
ペンギン先生 ペンギン先生
読み取りが多く、同時に読む処理に十分な長さがある場合などには有利になり得るよ。ただしRWロックの管理にも負荷がある。読み取りが短い場合や更新が多い場合には、性能が改善しないこともあるんだ
ひよこ ひよこ
どの仕組みを使うの?
ペンギン先生 ペンギン先生
JavaのReadWriteLockは、読み取り用と書き込み用のロックを組にする例だよ。Pythonのthreading.RLockは同じスレッドが再取得できる排他ロックで、複数の読み手を同時に通すRWロックとは機能が違うんだ
ひよこ ひよこ
読み手優先や公平方式って?
ペンギン先生 ペンギン先生
書き手が待っていても読み手を受け入れ続けると、書き手が進めない飢餓が起き得る。書き手を優先する方式では、新しい読み手を待たせる。公平性の保証や取得順は実装ごとに確認しよう。JavaのReentrantReadWriteLockは既定が非公平で、公平モードも選べるよ
ひよこ ひよこ
データベースでも同じルール?
ペンギン先生 ペンギン先生
同時実行を調整する目的は共通でも、方式はいろいろだよ。PostgreSQLのMVCCは、通常の読み取りでデータのスナップショットを使い、読み取りと書き込みが互いを妨げにくくする。基本のRWロックと同じ仕組みとして説明するのは避けよう
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「読者-書き手問題」って出てきたら「読むのは同時OK、書く間は読み手も含めて独占する並行制御の問題」と思えばだいたいOK!
📖 おまけ:英語の意味
「Readers-Writers Problem」 = 読み手と書き手の問題
💬 Readerは共有データを読む処理、Writerは変更する処理を指すよ。読書や文章の書き方ではなく、アクセスをどう調整するかの問題なんだ

参考資料

← 用語集にもどる