Обмен технологиями

Подробное объяснение и применение Semaphore (семафора) в C#.

2024-07-12

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


Вставьте сюда описание изображения


В параллельном программировании синхронизация является основным требованием. Семафор — это общий механизм синхронизации, используемый для управления доступом к общим ресурсам. В C# семафоры реализуются через класс Semaphore в пространстве имен System.Threading. В этой статье подробно описывается семафор и его приложения на C#.

1. Что такое семафор?

Семафор — это целочисленное значение, которое можно использовать для управления доступом к общему ресурсу. Семафоры в основном используются для двух целей:

Взаимоисключающий: Убедитесь, что только один поток может одновременно обращаться к общим ресурсам.
считать: Разрешить определенному количеству потоков одновременный доступ к общим ресурсам.
Семафоры обычно используются в следующих сценариях:

  • Ограничьте одновременный доступ к ресурсам, например ограничив количество подключений к базе данных.
  • Синхронизация чтения и записи данных в задаче производитель-потребитель.
  • Синхронизируйте доступ к общим ресурсам между несколькими процессами.

2. Класс семафора в C#

В C# класс Semaphore обеспечивает базовые операции с семафорами. Чтобы создать семафор, используйте следующий синтаксис:

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

InitialCount: начальное значение счетчика семафора, указывающее значение семафора при его создании.
MaximumCount: максимальное значение счетчика семафора, указывающее максимальное значение, которого может достичь семафор.

3. Примеры использования семафоров

3.1 Создайте семафор

В C# создайте семафор, используя класс SemaphoreSlim. Этот класс представляет собой реализацию контекста синхронизации Semaphore, обеспечивающую более гибкие асинхронные операции.

с использованием System.Threading;

публичный класс SemaphoreExample
{
частный 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

В этом примере мы создаем семафор, который позволяет одновременно выполнять метод Work до 3 потоков. Каждый поток пытается получить семафор при вызове semaphore.WaitOne(). Если значение семафора больше 0, поток продолжит выполнение. В противном случае поток будет заблокирован до тех пор, пока другой поток не освободит семафор.

Асинхронные операции
Класс SemaphoreSlim также предоставляет асинхронные методы ожидания и выпуска:

  1. await semaphore.WaitAsync(): асинхронно ждать семафора
  2. await semaphore.ReleaseAsync(): асинхронно освободить семафор

Это делает использование семафоров более гибким и лучше интегрируемым с моделями асинхронного программирования.

4. Резюме

Семафор (семафор) в C# — это мощный механизм синхронизации, который может помочь разработчикам контролировать доступ к общим ресурсам. Используя семафоры, мы можем эффективно управлять доступом нескольких потоков к общим ресурсам, гарантируя, что использование ресурсов не приведет к гонкам данных или другим проблемам синхронизации.

Важность семафора в программировании на C# отражается в его способности помогать разработчикам реализовывать сложную логику управления параллелизмом, сохраняя при этом читабельность и удобство обслуживания кода. Простота использования отражается в простом дизайне API и богатой поддержке контекста синхронизации.

В практических приложениях семафоры можно использовать для ограничения размера пула подключений к базе данных, управления доступом к сетевым ресурсам, достижения синхронизации модели производитель-потребитель и т. д. Мы надеемся, что благодаря этой статье читатели смогут лучше понять принципы и использование семафора и использовать его преимущества в реальных проектах.