ロック
 
 
 

ロックは、シングル スレッドのみがいつでもコードをトラバースできるように、コードの領域を定義するオペレータです。また、ロックはミューテックス(相互排除)とも呼ばれますが、この言葉は OS によっては若干意味が異なる場合があります。代表的な例として、さまざまなスレッドからの 1 つのグローバル変数に対する複数同時書き込みの保護が挙げられます。たとえば、このコードが複数のスレッドからコールされる場合、次のようになります。

static int val=0;
LOCK;
val++;
UNLOCK;

ロックが適切でなかった場合、2 つのスレッドが同時に val の修正を試行でき、双方ともは読み取り、更新、書き込みを個別のステージで行うため、正しい結果が出ません。これは競合状態と呼ばれます。これについては、後半で詳細に説明します。

ロックは再帰的であるため、同じスレッドが同じロックを複数回取得できます。ただし、これは一般的には危険性の高いコーディング手法とされます。ロックと同じ回数ロックを解除できなかった場合、ハングが発生し、ロックが解放されなくなってしまうためです。

競合状態を回避してロックを適切に管理することは、スレッド化の中で最も困難な作業の 1 つです。

アトミック操作

現在最新のプロセッサは、変数に対して所定のアトミック操作を実行できます。つまり、他のスレッドの実行から見ると、操作は 1 回の手順で完了するように見えます。結果として、このようなアトミック操作では修正操作中に別スレッドから値を読み取ることができないため、競合状態が生じることはなく、ロックも不要になります。オペレーティング システムによっては、このようなアトミック操作をハードウェアで直接コールできる低レベルの機能が用意されています。この操作は、ユーザ ロックの適用よりもはるかに高速であるため、できれば常時使用することをお勧めします。

セマフォとシグナル

セマフォは、ミューテックス ロックを一般化したものです。単純な boolean 状態のミューテックス ロックとは異なり、セマフォには内部カウンタがあります。内部カウンタは、スレッドからセマフォに対してロックされたリソースへのアクセスが要求されるたびにデクリメントし、スレッドがリソースを解放するたびにインクリメントします。カウンタがゼロになると、保持されているスレッドのいずれかのリソースが解放されるまで、リソースの獲得を試行する他のスレッドは遮断されます。したがって、セマフォに初期値として 5 を指定した場合、同時にリソースにアクセスできるスレッドは最大で 5 つまでです。

pthread の OSX プラットフォーム固有の問題

OSX pthread の実装は POSIX 標準に準拠しますが、Linux で使用可能なすべての pthread と関連機能が含まれているわけではありません。Mac OS X プラットフォーム固有の pthread の課題に詳細情報が記載されています。これは OS X で直接 pthread を使用して作業するすべてのユーザにとって重要となります。

ネイティブ スレッドの使用

このようなスレッド化の基礎は、シングル プラットフォームで低レベルで処理する場合に役立ちます。実装が異なるため、クロスプラットフォーム アプリケーションで使用する場合は複雑になります。後半で説明する一部の高レベルのスレッド化実装と比較すると、多数の処理が必要です。ただし、優先順位やアフィニティなどの操作を含むスレッドの動作を根本的に制御する必要がある場合、ネイティブ スレッドを選択するのが最適です。