C# でのマルチスレッド: 利点、基本、ベスト プラクティス

公開: 2023-06-01

目次

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

マルチスレッドはソフトウェア エンジニアリングの基本概念です。 C# では、.NET Framework を使用するソフトウェア開発者にとってマルチスレッド プログラミングが不可欠です。 複雑で応答性の高いアプリケーションを効率的に作成できるため、開発者はC# のマルチスレッドを広く使用しています

このブログでは、C# マルチスレッドの概要を説明すると同時に、プログラマーがスレッドを簡単に作成および管理する方法についても説明します。 マルチスレッドを使用する利点や、C# で使用できるさまざまなスレッド モデルも含まれます。

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

マルチスレッドを同時に実行すると、アプリケーションの効率が向上します。 C# スレッドの最も一般的な利点は次のとおりです。

  • アプリケーションのパフォーマンスの強化:マルチスレッドの助けにより、同じ空間で複数のタスクを実行するアプリケーションの実行が高速化されます。全体として、実行時間が短縮され、複数のタスクに道が譲られます。
  • スループットの向上: C# でのマルチタスクにより、アプリケーションのスループットが向上します。2 つの異なるスレッドを同時に実行すると、時間とリソースを節約できます。
  • 応答性の向上:マルチスレッドの助けを借りて、プログラムがバックグラウンドで実行されている間、ユーザーはアプリケーションのフロントエンドにアクセスできます。
  • リソース使用率の向上:マルチスレッドにより、ユーザーはより効率的にシステム リソースにアクセスできるようになります。たとえば、スレッドはファイル、メモリ、I/O デバイスなどのリソースを共有し、効率化への道を開くことができます。
  • よりアクセスしやすいプログラミング:マルチスレッドを使用すると、ユーザーが独立してスレッドを作成できるため、プログラミングが容易になります。また、ユーザーがアプリケーションを単独でデバッグおよびテストできるようになります。
  • 最適化された通信:スレッド同期により、プロセス間の通信が向上します。スレッド間の通信をよりアクセスしやすくするために使用できます。

まず、同期できる単一のオブジェクトに影響します。 次に、System.Threading および Interlocked クラスで使用できます。

C# におけるマルチスレッドの基本概念

マルチスレッドにより、ユーザーは複数のプロセッサ コアを利用して複数のタスクを同時に実行できます。 マルチスレッドで使用される基本概念は次のとおりです。

  • スレッド:スレッドは、プロセスの実行を支援するマルチスレッドの基本単位です。これらは、他のスレッドと同時に実行できる、特定のプログラム内の実行パスです。

C# では、フォアグラウンド スレッドとバックグラウンド スレッドという 2 種類のスレッドがあります。 平均的なスレッド クラスには、名前、優先度、isAlive、ThreadState、Start()、Suspend()、Resume()、および Join() が含まれます。

  • スレッド プール:スレッド プールは、タスクの実行を支援するスレッドです。これにより、オペレーティング システムが既存のスレッドを再利用できるようになり、発生する可能性のあるオーバーヘッドのリスクが最小限に抑えられます。
  • 同期: 同期により、複数の操作に対する他のスレッドへのアクセスが見落とされます。これは、データの整合性を維持し、オーバーヘッドを防ぐために不可欠なプロセスです。
  • デッドロック:デッドロックは、2 つのスレッドがリソースを共有し、続行しようとしても成功しない場合に発生するエラーです。システムがフリーズしたり、待ち時間が発生したりする可能性があります。
  • 非同期プログラミング:非同期プログラミングを使用すると、メインスレッドを中断せずに実行しながら、バックグラウンドで複数のタスクを実行できます。これにより、複数の応答性の高いユーザー インターフェイスへの道が開かれ、アプリケーションのパフォーマンスが向上します。

スレッドの作成と実行

これらの例を使用すると、作成と実行が簡単になります。 C # マルチスレッドの例を以下に示します。

システムを使用する;

System.Threading を使用します。

クラス プログラム {

静的 void Main() {

int ワーカーインデックス = 0;

スレッドworkerThread = new Thread(new ThreadStart(Worker));

ワーカースレッド.Start();

for (int mainIndex = 1; mainIndex <= 10; mainIndex++) {

Console.WriteLine(“メインスレッド: {0}”, mainIndex);

Thread.Sleep(200);

}

ワーカースレッド.Join();

}

static void Worker() {

for (int workIndex = 1; WorkerIndex <= 10; WorkerIndex++) {

Console.WriteLine(“ワーカー スレッド: {0}”, workerIndex * 2);

Thread.Sleep(200);

}

}

}

出力:

メインスレッド: 1

ワーカースレッド: 2

メインスレッド: 2

ワーカースレッド: 4

メインスレッド: 3

ワーカースレッド: 6

メインスレッド: 4

ワーカースレッド: 8

メインスレッド: 5

ワーカースレッド: 10

メインスレッド: 6

ワーカースレッド: 12

メインスレッド: 7

ワーカースレッド: 14

メインスレッド: 8

ワーカースレッド: 16

メインスレッド: 9

ワーカースレッド: 18

メインスレッド: 10

ワーカースレッド: 20

説明:この出力では、両方のスレッドが同時に動作して 1 ~ 10 と 2 ~ 20 の数値を出力し、後者はループ インデックスの 2 倍になります。この例では、 C# スレッド スリープ(Thread.Sleep) メソッドが使用されています。

同様に、フォアグラウンド スレッドを使用した別のC# スレッドの例を見ていきます。

システムを使用する;

System.Threading を使用します。

クラス プログラム {

静的 void Main() {

スレッド myThread = 新しいスレッド(ワーカー);

myThread.Start();

Console.WriteLine(“メインスレッド: 開始しました”);

for (int i = 1; i <= 5; i++) {

Console.WriteLine(“メインスレッド: カウント {0}”, i);

スレッド.スリープ(500);

}

Console.WriteLine(“メインスレッド: 終了しました”);

}

static void Worker() {

for (j = 1; j <= 5; j++) {

Console.WriteLine(“ワーカー スレッド: カウント {0}”, j * 3);

Thread.Sleep(750);

}

Console.WriteLine(“ワーカー スレッド: 終了しました”);

}

}

出力:

メインスレッド: 開始されました

ワーカー スレッド: カウント 3

メインスレッド: カウント 1

ワーカー スレッド: カウント 6

メインスレッド: カウント 2

ワーカー スレッド: カウント 9

メインスレッド: カウント 3

ワーカー スレッド: カウント 12

メインスレッド: カウント 4

ワーカー スレッド: カウント 15

メインスレッド: カウント 5

ワーカースレッド: 終了しました

メインスレッド: 終了しました

説明:この出力は、2 つのスレッドがどのように同時に動作するかを示しています。メイン スレッドとバックグラウンド スレッドは並行して動作するため、メイン スレッドは 1 ~ 5 の数値を出力します。ワーカー スレッドは 3 ~ 15 の倍数を出力します。

スキルアップのために upGrad のソフトウェア開発コースをチェックしてください。

ソフトウェア開発に関連する人気の記事を読む

なぜコーディングを学ぶのか? コードを学ぶにはどうすればよいですか? 特定のバージョンの NPM パッケージをインストールするにはどうすればよいですか? C++ における継承の種類 知っておくべきこと

スレッドの同期

スレッドの同期には、プログラム内の複数のスレッドの集合的な調整が含まれます。 これにより、プログラムが特定の順序で実行され、共有リソースにアクセスできるようになります。

C# では、lock キーワード、同期オブジェクト、Interlocked クラスなどの同期プリミティブを使用してこれが行われます。

C# スレッド同期のを以下に示します。

システムの使用;

System.Threading の使用;

クラスTablePrinter

{

パブリック void PrintTable()

{

ロック(これ)

{

for (int i = 3; i <= 8; i++)

{

Thread.Sleep(200);

Console.WriteLine(i*5);

}

}

}

}

クラスプログラム

{

public static void Main(string[] args)

{

TablePrinter tp = new TablePrinter();

スレッド t1 = 新しいスレッド(新しい ThreadStart(tp.PrintTable));

スレッド t2 = 新しいスレッド(新しい ThreadStart(tp.PrintTable));

t1.Start();

t2.Start();

}

}

出力:

15

20

25

30

35

40

45

50

55

60

ソフトウェア開発の無料コースを探索する

クラウド コンピューティングの基礎 ゼロから始める JavaScript の基本 データ構造とアルゴリズム
ブロックチェーン技術 初心者向けの反応 コア Java の基本
ジャワ 初心者向けの Node.js 高度なJavaScript

デッドロック

マルチスレッドにおけるデッドロックは、少なくとも 2 つ以上のスレッドがリソースのセットに依存している場合に発生します。 1 つのスレッドがヘルプへのルートを重複しているときに、もう 1 つのスレッドが同じことを実行しようとすると、デッドロックになります。

たとえば、スレッド A がリソース 1 にロックを持っており、スレッド B がリソース 1 を待っている間にリソース 2 へのアクセスを待機している場合、デッドロックが発生する可能性があります。

以下に例を示します。

システムを使用する;

System.Threading を使用します。

名前空間デッドロックincsharp

{

パブリッククラスの例

{

静的読み取り専用オブジェクト firstLock = new object();

静的読み取り専用オブジェクト SecondLock = new object();

静的 void ThreadJob()

{

Console.WriteLine(“\t\t\t\t最初のロックをロック中”);

ロック (firstLock)

{

Console.WriteLine(“\t\t\t\tLocked firstLock”);

Thread.Sleep(1500);

Console.WriteLine(“\t\t\t\tセカンドロックをロック中”);

ロック (秒ロック)

{

Console.WriteLine(“\t\t\t\tロックされた SecondLock”);

}

Console.WriteLine(“\t\t\t\tセカンドロックを解放しました”);

}

Console.WriteLine(“\t\t\t\tfirstLock を解放”);

}

静的 void Main()

{

new Thread(new ThreadStart(ThreadJob)).Start();

Thread.Sleep(1000);

Console.WriteLine(“秒ロックをロック”);

ロック (秒ロック)

{

Console.WriteLine(“ロックされた秒ロック”);

Console.WriteLine(“最初のロックをロック”);

ロック (firstLock)

{

Console.WriteLine(“ロックされたfirstLock”);

}

Console.WriteLine(“リリースされたfirstLock”);

}

Console.WriteLine(“秒ロックを解除”);

Console.Read();

}

}

}

出力:

ロック秒ロック

ロックされた秒ロック

最初にロックするロック

最初にロックされましたロック

最初にリリースされたロック

セカンドロックをリリース

需要の高いソフトウェア開発スキル

JavaScript コース コア Java コース データ構造コース
Node.js コース SQLコース フルスタック開発コース
NFTコース DevOps コース ビッグデータコース
React.js コース サイバーセキュリティコース クラウドコンピューティングコース
データベース設計コース Pythonコース 暗号通貨コース

スレッドプール

スレッド プールは、C# のマルチスレッド環境で複数の実行スレッドを管理するのに役立ちます。 これらにより、デッドロックを引き起こすことなく、すべてのスレッドが制御されたリソースにアクセスできるようになります。

スレッド プール マネージャーはスレッド プールを管理し、スレッドの作成、破棄、およびスケジュールを担当します。

TPL (タスク並列ライブラリ) を使用したスレッド プールの例を次に示します。

システムを使用する;

System.Threading.Tasks を使用します。

クラスプログラム

{

静的 void Main()

{

Task<string> task = Task.Factory.StartNew<string>

(() => DownloadString(“http://www.example.com/”));

文字列結果 = タスク.結果;

Console.WriteLine(結果);

Console.Read();

}

静的文字列 DownloadString(string uri)

{

using (var wc = new System.Net.WebClient())

wc.DownloadString(uri) を返します。

}

出力:

出力は、Web ページで利用可能なコンテンツによって異なります。 このプログラムは、指定された URL から Web ページのコンテンツを確実にダウンロードします。 その後、それらを印刷します。

タスク並列ライブラリ (TPL) を使用した非同期プログラミング

タスク並列ライブラリ (TPL) は、APIS とパブリック型を処理するための強力なツールです。 System.ThreadingSystem.Threading.Tasksを処理します

.NET Framework 4 は、並列コードの作成を目指す開発者向けに、言語およびフレームワーク レベルの API を提供します。 TPL の助けを借りて、非同期プログラミングでは、メインスレッドをブロックせずにプログラムを実行できます。

TPL を使用した非同期プログラミングの例を次に示します。

Task<string> task = Task.Factory.StartNew<string>(() => {

「結果」を返します。

});

文字列結果 = タスク.結果;

非同期タスク MyMethod() {

文字列結果 = タスクを待ちます。

}

無料のテクノロジー コースをチェックして、競合他社に差をつけてください。

C# でのマルチスレッドのベスト プラクティス

マルチスレッドは、パフォーマンスとマルチタスクの点で時間を節約できます。 マルチスレッドの仕組みについて詳しく知りたい場合は、 LJMU のコンピューター サイエンスの理学修士号を選択することができます

ユーザーが時間を節約し、最高の効率を記録できるようにするためのベスト プラクティスをいくつか紹介します。

  • スレッド セーフなコレクションを利用する: .NET Framework の同時コレクションは、すべてのコレクションのスレッド セーフ バージョンを提供するため、マルチスレッドの効率的な動作が容易になります。これらのコレクションには、リスト、クエリ、辞書が含まれます。
  • スレッド同期の実装:スレッド ツールの性質により、ユーザーはロック、モニター、セマフォを迅速に実装できます。
  • スレッド プーリングを使用する:スレッド プーリングの大部分はユーザーによって行われるため、マルチスレッドはシステムにとってより簡単かつ効率的になります。同時に、ユーザーはこれを使用してスレッドを自動的に作成できます。
  • スレッドローカル ストレージを使用する:マルチスレッドを実践する際、スレッドローカル ストレージを最適化し、複数のスレッドへのアクセスを提供することで、特定のリソースへのアクセスを確保します。
  • 可変状態の共有を避ける:可変状態の共有はバグや競合状態を引き起こすだけであり、注意が必要な場合があります。変更可能な状態は何としても避けてください。
  • 非同期モデルを使用する:非同期メソッドを使用すると、複数のタスクを新たに開始したりキューに残さずに並行して実装できます。
  • デッドロックを回避する:マルチスレッドを使用してプログラムを実行する場合、デッドロックが発生することが予想されます。プログラムを作成するときは、デッドロックを避けるために、スレッドを別のスレッドに続けて実行するようにしてください。
  • キャンセル トークンを使用する:キャンセル トークンを使用すると、スレッドを問題なく終了し、デッドロックを回避できます。

人気のソフトウェア エンジニアリング コースを探索する

LJMU および IIITB でコンピュータ サイエンスの理学修士号を取得 カリフォルニア工科大学 CTME サイバーセキュリティ証明書プログラム
フルスタック開発ブートキャンプ ブロックチェーンのPGプログラム
フルスタック開発におけるエグゼクティブ PG プログラム
以下のすべてのコースをご覧ください
ソフトウェアエンジニアリングコース

結論

C# のマルチスレッドは、高効率モデルが機能する重要な概念であり続けています。 これは、プログラマーがプログラムのワークロードを、同時に独立して実行される複数のタスクに分割する柔軟な方法を提供します。

マルチスレッド化は非常に有益ですが、慎重に実装しないと潜在的な障害につながる可能性があります。

2009 年から 2023 年の間に、進取的なソフトウェアに対する世界の予算は8,560 億ドルを超えており、ソフトウェア開発は開発者にとって輝かしいキャリアを約束しています。

upGrad のフル スタック ソフトウェア開発ブートキャンプ今すぐお申し込みください。 フルスタック開発コースは、コンピューター サイエンスの可能性を解き放ちたい開発者にとっての足がかりとなります。

1. マルチスレッド プログラミングとは何ですか?

マルチスレッド プログラミングは、複数のスレッドを同時に使用してプログラムを実行するプロセスです。 これにより、フロントエンドのユーザーは、コンピュータ上で実行されているプログラムの複数のコピーを中断することなく使用できるようになります。

2. スレッドとプロセスの主な違いは何ですか?

通常、プロセスには実行状態のプログラムが含まれますが、スレッドはサブプロセス内のプロセスで構成されます。

3. C# におけるスレッドとタスクの違いは何ですか?

C# のスレッドは、プログラミング用のスレッド プールの構築と管理を処理します。 一方、タスクはバックグラウンドで動作する非同期関数を表します。