これまでの連載で,Linuxカーネルの基本機能についてひと通り解説しました。しかし最近のUNIXカーネルは,ここまで紹介した基本機能に加えてさまざまな機能を装備しています。Linuxカーネルも例外ではなく,さまざまな分野で利用されるにつれ,多くの機能が実装されてきました。例えば,カーネルの機能を動的に(動作させたまま)拡張するモジュール機構や,それらのモジュールを自動的に導入するhotplug機構,そして電源管理などを行う APM/ACPI機構などです。

 今回はこうした機能のうち,地味ですがとても重要な排他制御機構に関して解説します。

排他制御はなぜ必要か

 Linuxは,マルチユーザー/マルチタスクのOSです。つまり,複数のユーザーが同時に複数のプログラム(プロセス)を実行できます。この機能は,以前に解説したように,プロセッサで実行するプロセスを細かく切り替える仕組みにより実現されています。しかし,複数のプログラムを安全に実行するには,ほかにも必要な仕組みがあります。

 例えば,カウンタの数値を1つ増やす処理を考えてみましょう。この処理は,(1)メモリーから現在の数値を読む,(2)数値を1つ増加させる,(3)メモリーに計算後の数値を書き込む,という3つの処理から主に成り立っています。この処理が必ず順番通り進めば,全く問題はありません。しかし,Linux のようなマルチタスクOSでは,同時に2つのプロセスがこの処理をする場合があります。このときは,いったいどうなるのでしょう。

 図1のように,プロセスAが計算後の数値を書き込む前にプロセスBが数値を読み込んでしまう場合を考えてみましょう。この場合,数値を増加させる処理は 2度実行されています。つまりカウンタの数値は2増えていなければなりません。しかし,カウンタの数値は1しか増えません。これではカウンタとして正しい動作を期待できません。

図1●排他制御をしない場合
図1●排他制御をしない場合
2つのプロセスで合計2度計算しても,カウンタの値は1しか増えていない。

 正しく動作させるには,カウンタの数値を処理するプログラムを,ある瞬間には1つに限定する必要があります。図2のように,(1)~(3)の一連の処理を一度に1つのプロセスだけに許可(排他的に許可)すれば正しく動作できます。

図2●排他制御をする場合
図2●排他制御をする場合
ある瞬間に,カウンタを参照,更新できるのを1つのプロセスだけに限定(排他制御)すれば,正常にカウンタ値が更新される。