マルチスレッドの概要

「マルチスレッド」という用語には次のような意味があります。

マルチスレッドとオペレーティングシステム

最近のオペレーティングシステムでは、多数の異なるユーザがプログラム (プロセス) を同時に実行できます。 1 つの中央処理装置 (CPU) が搭載されたハードウェアシステムでオペレーティングシステムが動作する場合は、厳密にはこれらのプロセスが同時に実行されません。プロセスが同時に実行されているように見えるのみです。 オペレーティングシステムは CPU とその他のシステムリソースを必要なプロセスに割り当て、これらのリソースを実行中のプログラムから別のプログラムに (プリエンプティブ方式で) 切り替えます。 このリソースの切替えにより、複数のプログラムが同時に実行されているように見えます。

最近の多数のオペレーティングシステムでは、これと非常に良く似た方法により、各プロセス内で複数のスレッドを使用できます。 ここでもまた、オペレーティングシステムは CPU とさまざまなリソースを個別のスレッドに割り当て、これらのリソースの割り当てを実行中のスレッドから別のスレッドに切り替えます。 そのため、複数のスレッドが同時に実行されているように見えます。

では、オペレーティングシステムがプロセスとスレッドを同じように処理するのであれば、この 2 つをどのように区別するのでしょうか ?

すべてのプロセスは、アドレス領域、オープンファイル、他のシステムリソースを個別にもっています。そのため、同時に実行されている他のプロセスに対して与える影響を最小限、または影響がない状態で、各プロセスを実行できます。 ただし、リソースを個別にもつことで、次のランタイムコストがかかります。

スレッドは 1 つのプロセス内で実行されるので、プロセスに関連するすべてのスレッドは、データおよびコードの同じアドレス領域、同じオープンファイル、その他の大部分のリソースを共有します。 また、各スレッドはそれぞれ固有のレジスタセットとスタック領域をもっています。 そのため、スレッドの作成には大量のシステムメモリは必要ありません。 同じプロセス内のあるスレッドから別のスレッドに実行コンテキストを切り替えるときに、オペレーティングシステムが行うことは CPU の所有権とレジスタセットの切替えのみです。 この理由により、スレッドはよく「簡易プロセス」と呼ばれます。

マルチスレッドとアプリケーション

マルチスレッドアプリケーションとは、オペレーティングシステムが提供するマルチスレッド機能を利用したアーキテクチャのアプリケーションを指します。 通常、マルチスレッドアプリケーションは、プロセス内の各スレッドに特定のジョブを割り当てます。各スレッドはさまざまな方法で互いに通信し合い、それぞれのアクションの同期を取ります。 たとえば、データ処理アプリケーションを設計する場合に、1 つのスレッドでグラフィックユーザインターフェイスを完全に処理し、別のスレッドでそのアプリケーションの実際の作業を行います。 このアーキテクチャにより、アプリケーション内の実際の作業とユーザインターフェイスを完全に分離できます。

他には、マルチスレッドアプリケーションをクライアント / サーバアプリケーションのサーバ側で使用する方法もあります。 サーバを設計する場合に、主コントローラスレッドまたは通信スレッドに送信されたそれぞれのサービス要求に対して、その要求を処理し、結果をコントローラに返す別のサービススレッドを作成できます。 このアーキテクチャにより、コントローラはこれらの結果をクライアントに送り返します。 このアーキテクチャの主な利点は、サーバが 1 つのクライアントの要求に拘束されて他のクライアントの要求に迅速に応答できないという事態が発生しないことです。

サーバから応答をただちに (または高速で) 得るクライアント / サーバアプリケーションは、従来、マルチスレッドを使用しないで作成されてきました。 これは、通常、主コントローラプロセスまたは通信プロセスが各クライアントの要求に対して個別のサービスプロセスを作成するために可能でした。 マルチスレッドがこれらのアプリケーションで必要とされる 主な理由は、システムリソースの有効利用です。

スレッドの作成時に必要なオペレーティングシステムのリソース (メモリ、コンテキストスワップのオーバヘッドなど) はわずかなので、ファイルや他のリソースを簡単に共有できます。 一方、プロセスの作成には、より多くのシステムリソースが必要なので、プロセス間で互いに通信したり、ファイルを共有したりすることがより難しくなります。 マルチスレッドを使用すると、既存のハードウェアリソースを最大限に利用し、リソースの共有を簡略化できます。

一方、マルチスレッドアプリケーションにも欠点があります。 各スレッドは、同じプロセスの他のスレッドと共有する可能性のあるリソースを認識している必要があります。 プログラマは、複数のスレッドが同時に実行されることに注意してください。また、2 つのスレッドが実行同期を取らずに同じデータ項目に書き込みを行うと、そのデータ項目が破損する可能性があります。

たとえば、次に示すコードを考えます。

Working-Storage Section.
01 group-item.
  05 field-1  pic x.
  05 field-2  pic x.
procedure division.
move 'A' to field-1
move 'B' to field-2
display group-item
Working-Storage Section.
01 group-item.
  05 field-1  pic x.
  05 field-2  pic x.
procedure division.
move 'C' to field-2
move 'D' to field-1
display group-item

次に示すスレッドの実行順序を考えます。

処理のステップ スレッド 1 の実行 スレッド 2 の実行
1 move 'A' to field-1
2 move 'C' to field-2
3 move 'B' to field-2
4 move 'D' to field-1
5 display group-item
6 display group-item

この例では、どちらのスレッドも予期した値を表示しません。 予期していたスレッド 1 の結果は 'AB' で、スレッド 2 の結果は 'DC' です。 ただし、両方のスレッドが実際に表示する値は 'DB' です。 マルチスレッドアプリケーションを作成する場合は、各スレッド間で実行の同期を取り、スレッド間でデータが競合しないようにしてください。詳細については、『実行の同期と競合の解決』の章で説明します。