技術共有

C#におけるSemaphore(セマフォ)の詳しい解説と応用

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina


ここに画像の説明を挿入します


並行プログラミングでは、同期が基本的な要件です。セマフォは、共有リソースへのアクセスを制御するために使用される一般的な同期メカニズムです。 C# では、セマフォは System.Threading 名前空間の Semaphore クラスを通じて実装されます。この記事では、C# でのセマフォとそのアプリケーションを詳しく紹介します。

1. セマフォとは何ですか?

セマフォは、共有リソースへのアクセスを制御するために使用できる整数値です。セマフォは主に 2 つの目的に使用されます。

相互に排他的: 共有リソースに同時にアクセスできるのは 1 つのスレッドだけであることを確認してください。
カウント: 一定数のスレッドが共有リソースに同時にアクセスできるようにします。
セマフォは通常、次のシナリオで使用されます。

  • データベース接続数の制限など、リソースへの同時アクセスを制限します。
  • プロデューサーとコンシューマーの問題におけるデータの読み取りと書き込みの同期。
  • 複数のプロセス間で共有リソースへのアクセスを同期します。

2. C# のセマフォ クラス

C# では、Semaphore クラスはセマフォの基本的な操作を提供します。セマフォを作成するには、次の構文を使用します。

Semaphore semaphore = new Semaphore(initialCount, maximumCount);
  • 1

InitialCount: セマフォの初期カウント値。作成時のセマフォの値を示します。
MaximumCount: セマフォの最大カウント値。セマフォが到達できる最大値を示します。

3. セマフォの使用例

3.1 セマフォの作成

C# では、SemaphoreSlim クラスを使用してセマフォを作成します。このクラスはセマフォの同期コンテキスト実装であり、より柔軟な非同期操作を提供します。

System.Threading を使用します。

パブリッククラス SemaphoreExample
{
private SemaphoreSlim semaphore = new SemaphoreSlim(3) // 3 つのスレッドが同時にアクセスできるようにカウント セマフォを作成します。

public void DoWork()
{
    semaphore.Wait(); // 获取信号量,如果信号量小于0,线程将被阻塞

    try
    {
        // 执行共享资源的操作
    }
    finally
    {
        semaphore.Release(); // 释放信号量
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}

3.2 セマフォを使用してスレッドを同期する

以下は、セマフォ リソースを作成、取得、解放する方法を示す簡単な例です。

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        // 创建信号量,允许3个线程同时访问共享资源
        Semaphore semaphore = new Semaphore(3, 3);

        // 创建和启动线程
        for (int i = 0; i < 10; i++)
        {
            new Thread(() => Work(semaphore)).Start();
        }
    }

    static void Work(Semaphore semaphore)
    {
        try
        {
            // 获取信号量
            semaphore.WaitOne();

            // 执行共享资源的操作
            Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} 正在执行。");
            Thread.Sleep(1000);
        }
        finally
        {
            // 释放信号量
            semaphore.Release();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

この例では、最大 3 つのスレッドが Work メソッドを同時に実行できるようにするセマフォを作成します。各スレッドは、semaphore.WaitOne() を呼び出すときにセマフォの取得を試みます。セマフォの値が 0 より大きい場合、スレッドは実行を継続します。それ以外の場合、スレッドは別のスレッドがセマフォを解放するまでブロックされます。

非同期操作
SemaphoreSlim クラスは、非同期の待機メソッドと解放メソッドも提供します。

  1. await semaphore.WaitAsync(): セマフォを非同期的に待ちます
  2. await semaphore.ReleaseAsync(): セマフォを非同期的に解放します

これにより、セマフォの使用がより柔軟になり、非同期プログラミング モデルとより適切に統合されます。

4. まとめ

C# のセマフォ (セマフォ) は、開発者が共有リソースへのアクセスを制御するのに役立つ強力な同期メカニズムです。セマフォを使用すると、共有リソースへの複数のスレッドのアクセスを効果的に管理でき、リソースの使用によってデータ競合やその他の同期の問題が発生しないようにできます。

C# プログラミングにおけるセマフォの重要性は、開発者がコードの可読性と保守性を維持しながら複雑な同時実行制御ロジックを実装できるようにするセマフォの機能に反映されています。その使いやすさは、シンプルな API 設計と豊富な同期コンテキストのサポートに反映されています。

実際のアプリケーションでは、セマフォを使用してデータベース接続プールのサイズを制限し、ネットワーク リソースへのアクセスを制御し、プロデューサー/コンシューマー モデルの同期などを実現できます。この記事の紹介を通じて、読者の皆様がセマフォの原理と使い方をより深く理解し、実際のプロジェクトで活用していただければ幸いです。