C# マルチスレッド完全マスター:パフォーマンスと効率を向上させる
スレッドとは、プログラムの実行パスとして定義されます。各スレッドは一意の制御フローを定義します。複雑で時間のかかる操作を伴うアプリケーションでは、異なる実行パス、つまりスレッドを設定し、各スレッドが特定のジョブを実行するようにすると便利です。
スレッドは軽量プロセスです。現代のオペレーティング システムによる並行プログラミングの実装が、スレッドの一般的な使用例の 1 つです。スレッドの使用により CPU サイクルの無駄を省き、アプリケーションの効率を向上させます。
これまで、単一のスレッドが単一のプロセスとして実行される(アプリケーションの実行インスタンス)プログラムを書いてきました。しかしこの方法では、アプリケーションは一度に 1 つのジョブしか実行できません。複数のタスクを同時に実行するには、より小さなスレッドに分割します。
スレッドのライフサイクル
スレッドのライフサイクルは、System.Threading.Thread クラスのオブジェクトが作成されたときに始まり、スレッドが終了または実行完了したときに終わります。
スレッドのライフサイクルにおける主な状態は以下の通りです。
未開始状態:スレッド インスタンスは作成されたが、Start メソッドが呼び出されていない状態。
準備完了状態:スレッドは実行可能で、CPU サイクルを待っている状態。
実行不能状態:以下の場合にスレッドは実行不能になります。
- Sleep メソッドが呼び出された
- Wait メソッドが呼び出された
- I/O 操作によってブロックされている
終了状態:スレッドが実行を完了したか、中止された状態。
メイン スレッド
C# では、System.Threading.Thread クラスを使用してスレッドを操作します。これにより、マルチスレッド アプリケーションで個々のスレッドの作成とアクセスが可能になります。プロセスで最初に実行されるスレッドをメインスレッドと呼びます。
C# プログラムの実行が開始されると、メイン スレッドが自動的に作成されます。Thread クラスを使用して作成されるスレッドは、メイン スレッドの子スレッドと呼ばれます。CurrentThread プロパティを使用して、現在実行中のスレッドにアクセスできます。
次のプログラムはメイン スレッドの実行を示しています。
ライブ デモusing System;
using System.Threading;
namespace MultithreadingApplication {
class MainThreadProgram {
static void Main(string[] args) {
Thread th = Thread.CurrentThread;
th.Name = "MainThread";
Console.WriteLine("This is {0}", th.Name);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
This is MainThread
Thread クラスの主なプロパティとメソッド
Thread クラスのよく使用されるプロパティの一部を以下に示します。
| 番号 | プロパティと説明 |
|---|---|
| 1 | CurrentContext スレッドが実行されている現在のコンテキストを取得します。 |
| 2 | CurrentCulture 現在のスレッドのカルチャを取得または設定します。 |
| 3 | CurrentPrincipal スレッドの現在のプリンシパル(役割ベースのセキュリティ用)を取得または設定します。 |
| 4 | CurrentThread 現在実行中のスレッドを取得します。 |
| 5 | CurrentUICulture リソース マネージャが実行時にカルチャ固有のリソースを検索するために使用する現在のカルチャを取得または設定します。 |
| 6 | ExecutionContext 現在のスレッドのさまざまなコンテキストに関する情報を含む ExecutionContext オブジェクトを取得します。 |
| 7 | IsAlive 現在のスレッドの実行状態を示す値を取得します。 |
| 8 | IsBackground スレッドがバックグラウンド スレッドかどうかを示す値を取得または設定します。 |
| 9 | IsThreadPoolThread スレッドがマネージド スレッド プールに属しているかどうかを示す値を取得します。 |
| 10 | ManagedThreadId 現在のマネージド スレッドの一意の識別子を取得します。 |
| 11 | Name スレッドの名前を取得または設定します。 |
| 12 | Priority スレッドのスケジューリング優先度を示す値を取得または設定します。 |
| 13 | ThreadState 現在のスレッドの状態を含む値を取得します。 |
Thread クラスのよく使用されるメソッドの一部を以下に示します。
| 番号 | メソッドと説明 |
|---|---|
| 1 | public void Abort() 呼び出されたスレッドで ThreadAbortException を発生させ、スレッドの終了プロセスを開始します。通常、このメソッドの呼び出しでスレッドが終了します。 |
| 2 | public static LocalDataStoreSlot AllocateDataSlot() すべてのスレッドで名前なしデータ スロットを割り当てます。パフォーマンス向上のため、ThreadStaticAttribute 属性が付いたフィールドの使用を推奨します。 |
| 18 | public void Start() スレッドを開始します。 |
| 19 | public static void Sleep(int millisecondsTimeout) 指定した期間、スレッドを一時停止させます。 |
| 23 | public static bool Yield() 呼び出し元のスレッドの実行を、現在のプロセッサで実行可能な別のスレッドに譲ります。 |
スレッドの作成
スレッドは Thread クラスを継承して作成します。拡張した Thread クラスは Start() メソッドを呼び出して子スレッドの実行を開始します。
次のプログラムはこの概念を示しています。
ライブ デモusing System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
Console.WriteLine("Child thread starts");
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
In Main: Creating the Child thread Child thread starts
スレッドの管理
Thread クラスはスレッド管理のためのさまざまなメソッドを提供します。
次の例は、Sleep() メソッドを使用してスレッドを特定の期間一時停止させる方法を示しています。
ライブ デモusing System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
Console.WriteLine("Child thread starts");
// スレッドを 5000 ミリ秒一時停止
int sleepfor = 5000;
Console.WriteLine("Child Thread Paused for {0} seconds", sleepfor / 1000);
Thread.Sleep(sleepfor);
Console.WriteLine("Child thread resumes");
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
In Main: Creating the Child thread Child thread starts Child Thread Paused for 5 seconds Child thread resumes
スレッドの終了
Abort() メソッドはスレッドの終了に使用されます。
ランタイムは ThreadAbortException をスローしてスレッドを中止します。この例外はキャッチできず、制御は finally ブロック(存在する場合)に移ります。
次のプログラムでこれを説明します。
ライブ デモusing System;
using System.Threading;
namespace MultithreadingApplication {
class ThreadCreationProgram {
public static void CallToChildThread() {
try {
Console.WriteLine("Child thread starts");
// 何らかの作業(例:10までカウント)
for (int counter = 0; counter <= 10; counter++) {
Thread.Sleep(500);
Console.WriteLine(counter);
}
Console.WriteLine("Child Thread Completed");
} catch (ThreadAbortException e) {
Console.WriteLine("Thread Abort Exception");
} finally {
Console.WriteLine("Couldn't catch the Thread Exception");
}
}
static void Main(string[] args) {
ThreadStart childref = new ThreadStart(CallToChildThread);
Console.WriteLine("In Main: Creating the Child thread");
Thread childThread = new Thread(childref);
childThread.Start();
// メイン スレッドを少し停止
Thread.Sleep(2000);
// 子スレッドを中止
Console.WriteLine("In Main: Aborting the Child thread");
childThread.Abort();
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
In Main: Creating the Child thread Child thread starts 0 1 2 In Main: Aborting the Child thread Thread Abort Exception Couldn't catch the Thread Exception
C言語
- 適切なネジ処理剤の選択:信頼性向上とダウンタイム削減
- 糸:種類、歴史、製造、品質管理
- デジタル スレッドを解き明かす:Siemens PLMのスマート製造ブループリント
- ネジの谷径と山径:正しいネジサイズ選びの基礎知識
- 糸切りカッター(スレッドカッター)の理解:種類、用途、応用
- 高速裏面照射型イメージセンサー:100万FPS超の撮影を実現
- Thread vs. ZigBee:IoTエンジニア向け技術比較
- エッジコンピューティングに明確な業界承認フレームワークが誕生
- C++マルチスレッド完全ガイド:効率的な並行プログラミング
- Pythonマルチスレッドプログラミング:効率的な並行処理テクニック
- Java マルチスレッド完全解説:概念、ライフサイクル、実践コード例