スレッド(コンピューティング)

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ
1つのプロセッサで実行される2つの実行スレッドを持つプロセス

コンピュータサイエンスでは実行スレッド、通常はオペレーティングシステムの一部であるスケジューラによって独立して管理できるプログラムされた命令の最小シーケンスです[1]スレッドとプロセスの実装はオペレーティングシステムによって異なりますが、ほとんどの場合、スレッドはプロセスのコンポーネントです。特定のプロセスの複数のスレッドは、メモリなどのリソースを共有して、(マルチスレッド機能を介して)同時に実行できます。、異なるプロセスはこれらのリソースを共有しませんが。特に、プロセスのスレッドは、実行可能コードと、動的に割り当てられた変数および非スレッドローカル グローバル変数の値をいつでも共有します。

歴史

スレッドは、1967年にOS / 360 Multiprogramming with a Variable Number of Tasks (MVT)で「タスク」という名前で早くから登場しました。Saltzer(1966)は、 Victor A.Vyssotskyに「スレッド」という用語を付けました。[2]

スレッド化の人気は2003年頃に増加しました。これは、CPU周波数の増加がコア数の増加に置き換わり、複数のコアを利用するために同時実行が必要になるためです。[3]

プロセス、カーネルスレッド、ユーザースレッド、およびファイバー

スケジューリングはカーネルレベルまたはユーザーレベルで実行でき、マルチタスクはプリエンプティブまたは協調的に実行できます。これにより、さまざまな関連概念が生まれます。

プロセス

カーネルレベルでは、プロセスには1つ以上のカーネルスレッドが含まれ、メモリやファイルハンドルなど、プロセスのリソースを共有します。プロセスはリソースの単位であり、スレッドはスケジューリングと実行の単位です。カーネルのスケジューリングは、通常、先制的に、またはあまり一般的ではありませんが、協調的に行われます。ユーザーレベルでは、ランタイムシステムなどのプロセス自体が複数の実行スレッドをスケジュールできます。Erlangのように、これらがデータを共有しない場合、通常はプロセスと呼ばれます[4]が、データを共有する場合、特に先制的にスケジュールされている場合は、通常(ユーザー)スレッドと呼ばれます。協調的にスケジュールされたユーザースレッドはファイバーと呼ばれます; プロセスが異なれば、ユーザースレッドのスケジュールも異なる場合があります。ユーザースレッドは、カーネルスレッドによってさまざまな方法(1対1、多対1、多対多)で実行できます。「軽量プロセス」という用語は、ユーザースレッド、またはユーザースレッドをカーネルスレッドにスケジュールするためのカーネルメカニズムをさまざまに指します。

プロセス作成、破棄、および切り替えには比較的コストがかかるため、プロセスはカーネルスケジューリングの「重量級」の単位です。オペレーティングシステムによって割り当てられた独自のリソースを処理します。リソースには、メモリ(コードとデータの両方)、ファイルハンドル、ソケット、デバイスハンドル、ウィンドウ、およびプロセス制御ブロックが含まれます。プロセスはプロセス分離によって分離され、ファイルハンドルや共有メモリセグメントの継承、または同じファイルの共有方法でのマッピングなどの明示的な方法を除いて、アドレス空間やファイルリソースを共有しません。プロセス間通信を参照してください。プロセスの作成または破棄は、リソースを取得または解放する必要があるため、比較的コストがかかります。プロセスは通常、プリエンプティブにマルチタスクであり、プロセスの切り替えは、キャッシュフラッシュなどの問題のために、コンテキスト切り替えの基本的なコストを超えて比較的高価です(特に、プロセスの切り替えによって仮想メモリのアドレス指定が変更され、無効化が発生し、タグなしのトランスレーションルックアサイドバッファがフラッシュされます。特にx86で)。

カーネルスレッド

カーネルスレッドは、カーネルスケジューリング の「軽量」ユニットです。各プロセス内に少なくとも1つのカーネルスレッドが存在します。プロセス内に複数のカーネルスレッドが存在する場合、それらは同じメモリとファイルリソースを共有します。オペレーティングシステムのプロセススケジューラがプリエンプティブである場合、カーネルスレッドはプリエンプティブにマルチタスクになります。カーネルスレッドは、スタック、プログラムカウンターを含むレジスタのコピー、およびスレッドローカルストレージを除いて、リソースを所有していません。(もしあれば)、したがって、作成および破棄するのは比較的安価です。スレッドの切り替えも比較的安価です。コンテキストスイッチ(レジスタとスタックポインタの保存と復元)が必要ですが、仮想メモリを変更しないため、キャッシュに適しています(TLBを有効のままにします)。カーネルは、システム内の各論理コアに1つのスレッドを割り当てることができ(マルチスレッドをサポートしている場合は各プロセッサが複数の論理コアに分割され、サポートされていない場合は物理コアごとに1つの論理コアのみをサポートするため)、ブロックされます。ただし、カーネルスレッドは、ユーザースレッドよりもはるかに長い時間がかかります。

ユーザースレッド

スレッドは、ユーザースペースライブラリに 実装されることがあります。つまり、ユーザースレッドと呼ばれます。カーネルはそれらを認識しないため、ユーザースペースで管理およびスケジュールされます一部の実装では、マルチプロセッサマシン(M:Nモデル)のメリットを活用するために、ユーザースレッドを複数のカーネルスレッドに基づいています仮想マシンによって実装されるユーザースレッドは、グリーンスレッドとも呼ばれます

ユーザースレッドの実装は通常、完全にユーザースペースにあるため、同じプロセス内のユーザースレッド間のコンテキスト切り替えは、カーネルとの対話をまったく必要としないため、非常に効率的です。コンテキスト切り替えは、で使用されるCPUレジスタをローカルに保存することで実行できます。現在ユーザースレッドまたはファイバーを実行していて、実行するユーザースレッドまたはファイバーに必要なレジスタをロードしています。スケジューリングはユーザースペースで行われるため、スケジューリングポリシーは、プログラムのワークロードの要件に合わせてより簡単に調整できます。

ただし、(カーネルスレッドではなく)ユーザースレッドでシステムコールをブロックすることは問題になる可能性があります。ユーザースレッドまたはファイバーがブロックするシステムコールを実行する場合、プロセス内の他のユーザースレッドおよびファイバーは、システムコールが戻るまで実行できません。この問題の典型的な例は、I / Oを実行する場合です。ほとんどのプログラムは、I / Oを同期的に実行するように作成されています。I / O操作が開始されると、システムコールが作成され、I / O操作が完了するまで戻りません。その間に、プロセス全体がカーネルによって「ブロック」されて実行できなくなり、同じプロセス内の他のユーザースレッドとファイバーの実行が不足します。

この問題の一般的な解決策(特に、グリーンスレッドの実装の多くで使用される)は、非ブロッキングI / Oを使用して、プロセス全体ではなく、呼び出し元のスレッドをブロックするインターフェイスを実装するI / OAPIを提供することです。内部で、I / O操作の進行中に別のユーザースレッドまたはファイバーをスケジュールします。他のブロッキングシステムコールにも同様のソリューションを提供できます。あるいは、同期I / Oまたは他のブロッキングシステムコールの使用を回避するようにプログラムを作成することもできます(特に、ラムダ継続および/または非同期/待機プリミティブを含む非ブロッキングI / Oを使用します[5])。

繊維

ファイバーは、協調的にスケジュールされるさらに軽いスケジューリング単位です。実行中のファイバーは、別のファイバーを実行できるように明示的に「譲歩」する必要があります。これにより、カーネルやユーザースレッドよりも実装がはるかに簡単になりますファイバーは、同じプロセスの任意のスレッドで実行するようにスケジュールできます。これにより、アプリケーションは、カーネルスケジューラ(アプリケーション用に調整されていない可能性があります)に依存する代わりに、スケジューリング自体を管理することでパフォーマンスを向上させることができます。OpenMPなどの並列プログラミング環境は、通常、ファイバーを介してタスクを実装します。繊維と密接に関連しているのはコルーチンです、コルーチンは言語レベルの構成であり、ファイバーはシステムレベルの構成であるという違いがあります。

プロセスに対するスレッド

スレッドは、いくつか の点で従来のマルチタスクオペレーティングシステムプロセスとは異なります。

WindowsNTOS / 2などのシステムは、安価なスレッドと高価なプロセスを備えていると言われています。他のオペレーティングシステムでは、アドレス空間スイッチのコストを除いてそれほど大きな違いはありません。一部のアーキテクチャ(特にx86)では、トランスレーションルックアサイドバッファ(TLB)がフラッシュされます。

スレッドとプロセスの長所と短所は次のとおりです。

  • スレッドのリソース消費量の削減:スレッドを使用すると、アプリケーションは、複数のプロセスを使用する場合よりも少ないリソースを使用して動作できます。
  • スレッドの共有と通信の簡素化:プロセス間通信(IPC)を実行するためにメッセージパッシングまたは共有メモリメカニズムを必要とするプロセスとは異なり、スレッドは既に共有しているデータ、コード、およびファイルを介して通信できます。
  • スレッドがプロセスをクラッシュさせる:同じアドレス空間を共有するスレッドが原因で、スレッドによって実行された不正な操作がプロセス全体をクラッシュさせる可能性があります。したがって、1つの不正なスレッドが、アプリケーション内の他のすべてのスレッドの処理を中断させる可能性があります。

スケジューリング

協調スケジューリングに対するプリエンプティブ

オペレーティングシステムは、スレッドをプリエンプティブまたは協調的にスケジュールします。マルチユーザーオペレーティングシステムは、一般に、コンテキストスイッチングを介した実行時間のよりきめ細かい制御のためにプリエンプティブマルチスレッドを好みます。ただし、プリエンプティブスケジューリングは、プログラマーが予期しない瞬間にスレッドをコンテキストスイッチする可能性があるため、ロックコンボイ優先順位の逆転、またはその他の副作用が発生します。対照的に、協調マルチスレッドはスレッドに依存して実行の制御を放棄するため、スレッドが完全に実行されるようになります。これは、協調的にマルチタスクのスレッドがブロックする場合に問題を引き起こす可能性がありますリソースを待機するか、集中的な計算中に実行の制御を譲らないことによって他のスレッドを枯渇させた場合。

シングル対マルチプロセッサシステム

2000年代初頭まで、ほとんどのデスクトップコンピューターにはシングルコアCPUが1つしかなく、ハードウェアスレッドはサポートされていませんでしたが、スレッド間の切り替えは一般にフルプロセスのコンテキストスイッチよりも高速であったため、このようなコンピューターではスレッドが引き続き使用されていました。2002年、Intelはハイパースレッディングという名前でPentium4プロセッサに同時マルチスレッディングのサポートを追加しました2005年に、彼らはデュアルコアPentium Dプロセッサを導入し、 AMDはデュアルコアAthlon 64X2プロセッサを導入しました。

シングルプロセッサを搭載したシステムは、通常、タイムスライシングによってマルチスレッドを実装します。中央処理装置(CPU)は、異なるソフトウェアスレッドを切り替えますこのコンテキスト切り替えは通常、スレッドまたはタスクが並列で実行されているとユーザーが認識するほど頻繁に発生します(一般的なサーバー/デスクトップオペレーティングシステムの場合、他のスレッドが待機しているときのスレッドの最大タイムスライスは、多くの場合100〜200ミリ秒に制限されます)。マルチプロセッサまたはマルチコアシステムでは、複数のスレッドを並行して実行でき、すべてプロセッサまたはコアが別々のスレッドを同時に実行します。ハードウェアスレッドを備えたプロセッサまたはコア上、個別のソフトウェアスレッドは、個別のハードウェアスレッドによって同時に実行することもできます。

スレッドモデル

1:1(カーネルレベルのスレッド化)

カーネル内のスケジュール可能なエンティティと1:1で対応してユーザーが作成したスレッド[6]は、可能な限り最も単純なスレッドの実装です。OS / 2Win32は最初からこのアプローチを使用していましたが、LinuxではGNU Cライブラリがこのアプローチを実装しています(NPTLまたは古いLinuxThreadsを介して)。このアプローチは、SolarisNetBSDFreeBSDmacOS、およびiOSでも使用されています。

N:1(ユーザーレベルのスレッド化)

N:1モデルは、すべてのアプリケーションレベルのスレッドが1つのカーネルレベルのスケジュールされたエンティティにマップされることを意味します[6]カーネルはアプリケーションスレッドの知識を持っていません。このアプローチを使用すると、コンテキストの切り替えを非常に迅速に実行でき、さらに、スレッド化をサポートしていない単純なカーネルでも実装できます。ただし、主な欠点の1つは、マルチスレッドプロセッサまたはマルチプロセッサコンピュータのハードウェアアクセラレーションの恩恵を受けられないことです。同時に複数のスレッドがスケジュールされることはありません。[6]例:スレッドの1つがI / O要求を実行する必要がある場合、プロセス全体がブロックされ、スレッドの利点を使用できません。TheGNU Portable Threadsは、 State Threadsと同様に、ユーザーレベルのスレッドを使用します

MN(ハイブリッドスレッディング)

MNは、いくつかのM個のアプリケーションスレッドをいくつかのN個のカーネルエンティティ[6]または「仮想プロセッサ」にマップします。これは、カーネルレベル( "1:1")とユーザーレベル( " N:1")のスレッド間の妥協点です。一般に、「MN」スレッドシステムは、カーネルとユーザースペースの両方のコードを変更する必要があるため、カーネルスレッドやユーザースレッドよりも実装が複雑です[説明が必要]M:N実装では、スレッドライブラリは、使用可能なスケジュール可能なエンティティでユーザースレッドをスケジュールする役割を果たします。これにより、システムコールが回避されるため、スレッドのコンテキスト切り替えが非常に高速になります。ただし、これにより、ユーザーランドスケジューラとカーネルスケジューラ間の大規模な(そして高価な)調整なしに、 複雑さと優先順位の逆転の可能性が高まり、最適化されていないスケジューリングが増加します。

ハイブリッド実装例

Unixシステムでのスレッドモデルの歴史

SunOS 4.xは、軽量プロセスまたはLWPを実装しました。NetBSD 2.x +、およびDragonFly BSDは、 LWPをカーネルスレッド(1:1モデル)として実装します。SunOS5.2からSunOS5.8、およびNetBSD2からNetBSD4は、2レベルのモデルを実装し、各カーネルスレッドで1つ以上のユーザーレベルのスレッドを多重化しました(M:Nモデル)。SunOS5.9以降およびNetBSD5は、ユーザースレッドのサポートを廃止し、1:1モデルに戻りました。[7] FreeBSD 5はM:Nモデルを実装しました。FreeBSD 6は1:1とM:Nの両方をサポートしており、ユーザーは/etc/libmap.confを使用して、特定のプログラムでどちらを使用するかを選択できます。FreeBSD 7以降、1:1がデフォルトになりました。FreeBSD 8は、M:Nモデルをサポートしなくなりました。

シングルスレッドプログラムとマルチスレッドプログラム

コンピュータプログラミングではシングルスレッドは一度に1つのコマンドを処理することです。[8]変数のセマンティクスとプロセス状態の正式な分析では、シングルスレッドという用語は、関数型プログラミングコミュニティで一般的な「シングルスレッド内のバックトラッキング」を意味するために別の方法で使用できます。[9]

マルチスレッドは、主にマルチタスクオペレーティングシステムで見られます。マルチスレッドは、1つのプロセスのコンテキスト内に複数のスレッドが存在できるようにする、広く普及しているプログラミングおよび実行モデルです。これらのスレッドはプロセスのリソースを共有しますが、独立して実行できます。スレッド化されたプログラミングモデルは、開発者に並行実行の有用な抽象化を提供します。マルチスレッドを1つのプロセスに適用して、マルチプロセッシングシステム での並列実行を可能にすることもできます。

マルチスレッドライブラリは、関数をパラメータとして受け取る新しいスレッドを作成するための関数呼び出しを提供する傾向があります。次に、渡された関数の実行を開始し、関数が戻ったときに終了する並行スレッドが作成されます。スレッドライブラリは、データ同期機能も提供します。

スレッドとデータの同期

同じプロセス内のスレッドは、同じアドレス空間を共有します。これにより、同時に実行されるコードを、 IPCのオーバーヘッドや複雑さなしに、緊密かつ便利にデータを交換することができますただし、スレッド間で共有する場合、更新に複数のCPU命令が必要な場合、単純なデータ構造でも競合状態になりやすくなります。2つのスレッドが同時にデータ構造を更新しようとして、予期せず足元で変化する可能性があります。競合状態によって引き起こされるバグは、再現および分離するのが非常に難しい場合があります。

これを防ぐために、スレッド化アプリケーションプログラミングインターフェイス(API)は、同時アクセスに対してデータ構造ロックするミューテックスなどの同期プリミティブを提供します。ユニプロセッサシステムでは、ロックされたミューテックスで実行されているスレッドはスリープ状態である必要があるため、コンテキストスイッチがトリガーされます。マルチプロセッサシステムでは、スレッドは代わりにスピンロック内のミューテックスをポーリングする場合があります。これらは両方ともパフォーマンスを低下させ、対称型マルチプロセッシング(SMP)システムのプロセッサにメモリバスを奪い合うことを強いる可能性があります。特に、ロックの粒度が細かすぎる場合はそうです。

その他の同期APIには、条件変数クリティカルセクションセマフォモニターが含まれます。

スレッドプール

スレッドを含む一般的なプログラミングパターンは、起動時に設定された数のスレッドが作成され、タスクが割り当てられるのを待つスレッドプールのパターンです。新しいタスクが到着すると、タスクはウェイクアップしてタスクを完了し、待機に戻ります。これにより、実行されるすべてのタスクで比較的高価なスレッドの作成および破棄機能が回避され、アプリケーション開発者の手からスレッド管理が不要になり、スレッド管理を最適化するのに適したライブラリまたはオペレーティングシステムに任せられます。

マルチスレッドプログラムとシングルスレッドプログラムの長所と短所

マルチスレッドアプリケーションには、シングルスレッドアプリケーションと比較して次の利点があります。

  • 応答性:マルチスレッドにより、アプリケーションは入力への応答性を維持できます。ワンスレッドプログラムでは、メインの実行スレッドが長時間実行されるタスクをブロックすると、アプリケーション全体がフリーズしたように見える場合があります。このような長時間実行されるタスクを、メインの実行スレッドと同時に実行されるワーカースレッドに移動することで、アプリケーションは、バックグラウンドでタスクを実行している間、ユーザー入力に応答し続けることができます。一方、ほとんどの場合、マルチスレッドはプログラムの応答性を維持する唯一の方法ではなく、非ブロッキングI / Oおよび/またはUnixシグナルを使用して同様の結果を得ることができます。[10]
  • 並列化:マルチコアまたはマルチCPUシステムの使用を検討しているアプリケーションは、マルチスレッドを使用してデータとタスクを並列サブタスクに分割し、基盤となるアーキテクチャでスレッドの実行方法を1つのコアで同時に、または複数のコアで並列に管理できます。CUDAOpenCLなどのGPUコンピューティング環境では、マルチスレッドモデルが使用され、数十から数百のスレッドが多数のコア上のデータ間で並行して実行されます。これにより、システムの使用率が向上し、(同期コストがメリットを損なうことがない場合)、プログラムの実行が高速化されます。

マルチスレッドアプリケーションには、次の欠点があります。

  • 同期の複雑さと関連するバグ:スレッド化されたプログラムに典型的な共有リソースを使用する場合、プログラマーは競合状態やその他の直感的でない動作を避けるように注意する必要がありますデータを正しく操作するために、スレッドはデータを正しい順序で処理するために時間内にランデブーする必要があることがよくあります。スレッドは、共通データが別のスレッドによって変更されているときに1つのスレッドで読み取られたり上書きされたりするのを防ぐために、相互に排他的な操作(多くの場合、ミューテックスを使用して実装されるこのようなプリミティブを不注意に使用すると、デッドロック、ライブロック、またはリソースをめぐる競争につながる可能性があります。エドワード・A・リーとして「スレッドはシーケンシャル計算からの小さなステップのように見えますが、実際には大きなステップを表しています。スレッドは、シーケンシャル計算の最も本質的で魅力的なプロパティである理解可能性、予測可能性、決定論を破棄します。スレッドは、計算は非常に非決定論的であり、プログラマーの仕事はその非決定論を取り除くことの1つになります。」[11]
  • テストできないこと一般に、マルチスレッドプログラムは非決定論的であり、その結果、テストできません。言い換えると、マルチスレッドプログラムには、テストシステムでは決して現れず、本番環境でのみ現れるバグが簡単に発生する可能性があります。[12] [11]これは、スレッド間通信を特定の明確に定義されたパターン(メッセージパッシングなど)に制限することで軽減できます。
  • 同期コスト最新のCPUのスレッドコンテキストスイッチは最大100万CPUサイクルのコストがかかる可能性があるため、[13]効率的なマルチスレッドプログラムの作成が困難になります。特に、スレッド間の同期が頻繁になりすぎないように、特別な注意を払う必要があります。

プログラミング言語のサポート

多くのプログラミング言語は、ある程度の容量でスレッド化をサポートしています。

  • IBM PL / I(F)には、早くも1960年代後半にマルチスレッド(マルチタスクと呼ばれる)のサポートが含まれていました。これは、最適化コンパイラー以降のバージョンでも継続されていました。IBM Enterprise PL / Iコンパイラーは、新しいモデルの「スレッド」APIを導入しました。どちらのバージョンもPL / I標準の一部ではありませんでした。
  • CおよびC ++の多くの実装はスレッド化をサポートし、オペレーティングシステムのネイティブスレッド化APIへのアクセスを提供します。スレッド実装の標準化されたインターフェイスは、C関数ライブラリ呼び出しのセットであるPOSIXスレッド(Pthreads)です。OSベンダーは必要に応じてインターフェイスを自由に実装できますが、アプリケーション開発者は複数のプラットフォームで同じインターフェイスを使用できる必要があります。Linuxを含むほとんどのUnixプラットフォームは、Pthreadをサポートしています。Microsoft Windowsには、 beginthreadのように、マルチスレッド用のprocess.hインターフェイスに独自のスレッド関数のセットがあります
  • JavaPython.NET Framework言語などの一部の高レベル(通常はクロスプラットフォーム)のプログラミング言語は、ランタイムでのスレッド実装におけるプラットフォーム固有の違いを抽象化しながら、開発者にスレッドを公開します。他のいくつかのプログラミング言語と言語拡張も、開発者からの並行性とスレッド化の概念を完全に抽象化しようとします(CilkOpenMPMessage Passing Interface(MPI))。一部の言語は、並行性やスレッドを必要とせずに、代わりに(特にGPUを使用して)順次並列化用に設計されています(Ateji PXCUDA)。
  • いくつかの解釈されたプログラミング言語には、グローバルインタープリターロック(GIL)のために、スレッド化と並行実行をサポートするが、スレッドの並列実行をサポートしない実装(Ruby用のRuby MRI 、Python用のCPythonなど)があります。GILは、インタープリターが保持する相互排除ロックであり、インタープリターが2つ以上のスレッドでアプリケーションコードを同時に解釈することを防ぐことができます。これにより、複数のコアシステムでの並列処理が効果的に制限されます。これにより、主にプロセッサを必要とするプロセッサバウンドスレッドのパフォーマンスが制限され、I / Oバウンドまたはネットワークバウンドスレッドのパフォーマンスはそれほど制限されません。Tclなどのインタプリタプログラミング言語の他の実装スレッド拡張を使用し、データとコードをスレッド間で明示的に「共有」する必要があるアパートメントモデルを使用して、GIL制限を回避します。Tclでは、各スレッドに1つ以上のインタープリターがあります。
  • データ並列計算用に設計されたCUDAなどのプログラミングモデルでは、スレッドの配列は、そのIDのみを使用して同じコードを並列に実行し、メモリ内のデータを検索します。本質的に、アプリケーションは、各スレッドがメモリの異なるセグメントで同じ操作を実行して、並列に操作してGPUアーキテクチャを使用できるように設計する必要があります。
  • Verilogなどのハードウェア記述言語には、非常に多数のスレッドをサポートする異なるスレッドモデルがあります(ハードウェアのモデリング用)。

も参照してください

参考文献

  1. ^ レスリー・ランポート(1979年9月)。「マルチプロセスプログラムを正しく実行するマルチプロセッサコンピュータの作り方」 (PDF)コンピューターでのIEEEトランザクションC-28(9):690–691。土井10.1109 /tc.1979.1675439S2CID5679366 _
  2. ^ 多重化されたコンピュータシステムの交通管制ジェロームハワードソルツァー、理学博士論文、1966年、20ページの脚注を参照。
  3. ^ ハーブサッター「フリーランチは終わった:ソフトウェアの並行性への根本的な転換」
  4. ^ 「Erlang:3.1プロセス」
  5. ^ セルゲイイグナチェンコ。「メッセージパッシングプログラムでノンブロッキングリターンを処理する8つの方法:C ++ 98からC ++ 11経由でC ++ 20へ」CPPCON。2021-11-04にオリジナルからアーカイブされました。
  6. ^ a b c d Gagne、Abraham Silberschatz、Peter Baer Galvin、Greg(2013)。オペレーティングシステムの概念(第9版)。ニュージャージー州ホーボーケン:ワイリー。pp。170–171。ISBN 9781118063330
  7. ^ 「Solarisオペレーティング環境でのマルチスレッド」(PDF)2002年。2009年2月26日のオリジナル(PDF)からアーカイブ。
  8. ^ RaúlMenéndez; ダグ・ロー(2001)。COBOLプログラマーのためのMurachのCICSマイク・ムラッハ&アソシエイツ。p。512. ISBN 978-1-890774-09-7
  9. ^ ピーター・ウィリアム・オハーン; RDテネント(1997)。ALGOLのような言語2.BirkhäuserVerlag _ p。157. ISBN 978-0-8176-3937-2
  10. ^ セルゲイイグナチェンコ。「シングルスレッド:バック・トゥ・ザ・フューチャー?」過負荷(97)。
  11. ^ a b エドワードリー(2006年1月10日)。「スレッドの問題」カリフォルニア大学バークレー校。
  12. ^ 「ビジネスロジックレベルでのマルチスレッドは有害であると見なされます」ACCU。
  13. ^ 'バグなし'うさぎ。「CPUクロックサイクルの運用コスト」

さらに読む

  • David R. Butenhof:POSIXスレッドを使用したプログラミング、Addison-Wesley、ISBN 0-201-63392-2 
  • Bradford Nichols、Dick Buttlar、Jacqueline Proulx Farell:Pthreads Programming、O'Reilly&Associates、ISBN 1-56592-115-1 
  • Paul Hyde:Java Thread Programming、Sams、ISBN 0-672-31585-8 
  • Jim Beveridge、Robert Wiener:Win32のマルチスレッドアプリケーション、Addison-Wesley、ISBN 0-201-44234-5 
  • Uresh Vahalia :Unix Internals:The New Frontiers、Prentice Hall、ISBN 0-13-101908-2