「ソフトウェアトランザクショナルメモリ」の版間の差分

削除された内容 追加された内容
タグ: 差し戻し済み
65行目:
 
== 不透明性 ==
楽観的な読み出しを伴うソフトウェアトランザクショナルメモリの実装には一つ問題がある。それは、実行中の(完了していない)トランザクションは、一貫性の破れた状態を読んでしまっていることがあるというものである(つまり、他のトランザクションによる更新の前の値と後の値を混ぜて読んでいることがある)。このようなトランザクションは、例え <code>atomic</code> ブロック内の終端まで処理が進んだとしても必ずアボートされる運命にあるので、トランザクションシステムによって強制される一貫性条件が破られるわけではない。しかし、この''仮の''矛盾した状態のために、[[セグメント方式|セグメンテーション]]フォールトやゼロ除算のような致命的な例外(fatal exception) を引き起こしたり、[[無限ループ]]に陥ってしまうことはありうる。"「{{lang|en|Language Support for Lightweight Transactions" }}」の図4にある作られた例を示す。
 
{| class="wikitable" border="1" style="width:auto; margin:1em auto;"
90行目:
最初に関係 ''x=y'' が成り立っていたとすると、上記のどちらのトランザクションもこの関係を崩すことはない([[不変条件]]になっている)。しかし、トランザクション A の処理において、''x'' をトランザクションBによる更新前に読み、一方 ''y'' をトランザクションBによる更新後に読み、結果として無限ループに陥るということは起こり得る。これは既に致命的な状態に陥っているにも関わらずトランザクションが継続されるためゾンビトランザクションとも呼ばれる。この問題へ対策としては、致命的な例外を横取りし、それぞれのトランザクションが正常かどうかを定期的にチェックし、異常ならばトランザクションをアボートするという方法があるが、言語によっては実装も大掛かりになりがちである。
 
ゾンビトランザクションに対して定期チェックなどを行わず、そもそも''腐った''値を読み出さない保の事を'''不透明性(Opacity)'''と呼ぶ。
不透明性を保障する方法として単純なものにIncremental'''漸進的な検証'''<ref>{{lang-en-short|incremental Validationvalidation}}</ref>が挙げられる。これは新しく値を読むたびにこれまでに読んだ値が以前に読んだ値と一致している事を確かめる物である。例えばあるトランザクションの中でA,B,Cの3つの変数を読み出す場合「Aを読む→Bを読む際にAも読んで前回と一致する事を確かめる→Cを読む際にA,Bも読んで前回と一致することを確かめる」という手順を踏むこととなり、読み出し操作は変数の数に対し''<math>O(n<sup>^2)</supmath>)'' でスケールする。
他にグローバルバージョンクロックを用いる手法もある。トランザクションが完了するごとにインクリメントされる共有カウンタを用意しておき、値を読み出す側がカウンタをチェックする事で他のトランザクションによる書き換えを検知する方法である。カウンタの値が増えている場合にIncremental Validation漸進的な検証と同様に再チェックを行う手法や、書き換え時のカウンタの値を保護対象のメモリと同時に書き込んでおくことによって、無駄な再チェック無しに値の非一貫性を検知する手法がある。
不透明性を保障しているソフトウェアトランザクショナルメモリはこれらの手法を用いる事で非一貫な値を読みそうになった時にアボートする。