Operating System Lecture 6/5

Operating System Lecture 6/5

先週の復習 -- Thread上の同期機構

Process Level Synchronization



Lock and Transaction

同期機構で実現したいのはConsistencyである。ただ、やみくもに同期機構を 使ってもConsistencyは得られない。例えば、lock によって直列可能性を 得るには、きまった方法によりlockをかける必要がある。一つのresource (資源)しかない場合には、lock は自明であるが、複数のresourceがある場合には、 lock をかける順序を工夫する必要がある。この問題は、データベースの 理論と同じ問題である。


Decd lock 閉塞

同期機構は、なんらかの待ちあわせを含む。この時に、いくつかのプロセスが 相互に待ちあわせてしまうことがある。これをDeck lockという。

問題1:

ある町のホテルの空室数をX、この町にいく飛行機の空席数をYとする。


以下のような操作を考えよう。 質問: さてSとTは、両方とも「飛行機の切符とホテルの予約」を取るという トランザクション(transaction)を実行したい。

一般的に複数のリソースを使うトランザクションでは、すべてをロ ックしてから処理をおこない、不要になったリソースからアンロッ クすることにより、矛盾を避けることができる。これを2 phase lock (2相ロック)という。しかし、2相ロックだけでは、デッドロックは、 避けることはできない。

読みだしの場合は、複数のプロセスから読みだしが あってもよい。これを利用して並列度を上げることが考えられる。 これを可能にするにはロックに段階をもうける。

shared lock どうしは、複数同時にかかる。しかし、exclusive lockは、 shared lock , exclusive lock ともにlockする。

select/client/server

ロックは結構難しい概念なので、より簡単な方法として、クライアント・ サーバモデルというのを使う場合がある。この場合は、サーバと呼ばれる プロセスを立ち上げ、サービスの要求はすべて、そこに転送される。 サービスは要求が到着した順に処理される。この時に、Unix では tcp socket と select というシステム・コールによりメッセージの選択が行われる。 この実験は後期のinfo2で行う。

この方法では、メッセージの到着順序により整合性が保たれる。しかし、 クライアント間の並列性がなくなるため、パフォーマンスは劣化する。

さらにこの欠点を緩和するために、サーバをマルチスレッド化すること が行われている。この場合は、サーバ内部で同期機構をまた別に使う 必要がある。同期機構としてはセマフォやロックが使われる。


アボート

多数のユーザがデータベースにアクセスする時に、2相ロックを使うと データベースの矛盾を防ぐことができる。しかし、デッドロックは 防ぐことができない。ロックするデータに順序付けをすればデッドロックは 防ぐことができるが、平行実行の制限が大きくなるのと、データの順序づけが 難しいので、あまり好まれない。

実際には、トランザクション一つにつきロックを一つだけとるような方法が 簡単であり効果的だ。しかし、この方法は一度にたくさんのアクセスが来る 場合には適さない。

もし、データのアクセス頻度が大きく、デッドロックは稀にしか起きない のならば、「取りあえずロックしていく。 ロックがとれないようだったら、しばらく待って、あきらめる」という方法が ある。(楽観的平行制御 Optimistic Concurrency Control)

この場合、あきらめたトランザクションは、今まで行った作業の取り消し をおこなう必要がある。これをトランザクションの アボート(abort)という。 アボートは、ディスクアクセスなどに失敗した場合、その他、 アプリケーションの都合によっても起きる。

例

前の例題で、飛行機だけ予約が取れても、ほてるだけ予約が取れても、役に たたない。もし、それぞれの残りが一つの場合、SとTが飛行機とホテルを別々に 予約できてしまう。(そして、お互いにキャンセル待ちに入る...) そうしない ためには、飛行機とホテルをセットにすれば良かった。

セットにしない場合でも、飛行機とホテルの予約をとって、どちらかが 取れなかったらアボートするという方法でも良い。この時にも、予約の 順序を決めると、それぞれが一つづつ残っているのに誰も予約できなかった というようなこと防ぐことができる。


カスケーディングアボート

一つのトランザクションがアボートしたとする。もし、そのトランザクションの データを他のトランザクションが使っていたとすると、そのトランザクションは だめになってしまう。つまり、そのトランザクションもアボートしなければ ならない。このようにアボートが連鎖的に起こることをカスケーディング アボート(Cascading Abort)という。

2相ロックを使っていれば、通常はロックによるアボートでは、 カスケーディングアボートは起こらない。しかし、その他の要因による アボートではカスケーディングアボートが無制限に起きる可能性がある。

これを防ぐには、2相ロックの解除を徐々にではなく、一度に行えば 良い。(狭義の2相ロック) しかし、この方法もアクセス頻度が大きい場合には並列度を 下げるので嫌われることが多い。





コミットとログ