2009年3月9日月曜日

マルチスレッドについて(3)

 今回は、同期保護について書いてみます。トランザクション処理(上)の7.3によると、同時に並行して同じデータを読み書きするトランザクション(スレッド)T1,T2に対して、次の4つに類型されます。
  1. 更新の消失  T2 READ -> T1 WRITE -> T2 WRITE
  2. ダーティリード T2 WRITE -> T1 READ -> T2 WRITE
  3. 非再現リード T1 READ -> T2 WRITE -> T1 READ
  4. 正常 T1 READ -> T2 READ -> T1 READ
具体的に考えてみると、更新の消失では、1枚の似顔絵を一旦、手元にコピーして、T1はモヒカンを書き加えて戻したが、T2は髭を書き加えて戻したので、T1の書いたモヒカンが消失してしまった状態を言います…(余計、わかりにくくなってしまったかも)。2つのトランザクションに対して、正常なのは読取(READ)の組み合わせのみとなります。

 ちょっと難しそうですが、補足すると、こうなります。
  1. 更新の消失  T2 READ -> T1 WRITE (->T1READ) -> T2 WRITE
  2. ダーティリード T2 WRITE (->T2READ) -> T1 READ -> T2 WRITE
  3. 非再現リード T1 READ -> T2 WRITE (->T2READ) -> T1 READ
 非再現リードは、避けようがないじゃないか!と文句をたれたくなるかもしれませんが、これは、T1 が一連のトランザクション処理を行う間に他のトランザクションによって書き換えられたら、一貫性がないよ!という意味になります。トランザクションが分離していれば問題はありません。

 こういうような事をじっくり解説した本は、おそらくトランザクション処理(上)トランザクション処理(下)を置いて他には皆無であり、選択肢が無いと感じています。この本、豚のように厚くて重たくて割れやすい上に書いてある事が一部おかしいのではないか?という代物で、読もうと思ったら拷問以外の何者でもないのですが、他に同じような本がありません。もし、他にあれば推薦して欲しいです。

 脱線してしまいましたが、従って、スレッド間で共有してアクセスする変数は、アクセス境界で整合性を保てるように不整合となるアクセスを保護(ブロック)しなければなりません。カウンタやポインタをスレッド間で共有する場合には、整合性を取れないと、お亡くなりになったり、悲惨な目にあいます。

 スレッド間で共有すべき変数は最小にして、かつ、最短の処理で
  • READ -> 処理 -> WRITE
  • READ -> 処理
しなければなりません。正常なパターンとして、READ -> READ の組み合わせがありましたので、これを応用したパターンが、Reader - Writer - Lock パターンです。複数の読み手か、単一の書き手で同期保護(ロック)をかけるというものです。
・・・続く

0 件のコメント: