マルチスレッドのプログラミング

データロック

データロックは、データ集合へのアクセスが一貫性をもって行われることを保証します。データロックも、基本的な概念はコードロックと同じです。しかし、コードロックは共有される (大域的な) データのみへの参照を囲むようにかけます。相互排他ロックでは、各データ集合に対応する危険領域を同時に実行できるスレッドはせいぜい 1 つです。

一方、複数読み取り単一書き込みロックでは、それぞれのデータ集合に対して複数スレッドが同時に読み取り操作を行うことができ、1 つのスレッドが書き込み操作を行うことができます。複数のスレッドが個別のデータ集合を操作する場合には、1 つのモジュール内で複数のスレッドを実行できます。特に、複数読み取り単一書き込みの場合には、1 つのデータ集合に対するスレッドの競合は発生しません。つまり、通常はコードロックよりもデータロックの方が、多重度を高くすることができます。

プログラムで mutex、条件変数、セマフォーなどのロックを使用するときに、どのような方法を使用すればよいかを説明します。できる限り並列性を高めるためにきめ細かくロックする、つまり必要なときだけロックして不要になったらすぐ解除するという方法がよいでしょうか。それとも、ロックと解除に伴うオーバヘッドをできる限り小さくするため長期間ロックを保持する、つまりきめの粗いロックを行うほうがよいでしょうか。

ロックをどの程度きめ細かくかけるべきかは、ロックによって保護されるデータの量によって異なります。もっともきめの粗いロックは、全データを 1 つのロックで保護します。保護対象のデータをいくつに分割してロックするかは、非常に重要な問題です。ロックのきめが細かすぎても、性能に悪影響を及ぼします。それぞれのロックと解除に伴うオーバーヘッドは、アプリケーション内のロックの数が多いと無視できなくなるからです。

一般には、きめの粗いロックから始めてボトルネックを特定し、その軽減のために必要な場所に、きめの細かいロックを追加します。これは妥当な解決策ですが、並列性を最大にすることとロックに伴うオーバーヘッドを最小にすることのどちらをどの程度優先させるかは、ユーザーが判断してください。