기술나눔

C#의 Semaphore(세마포어)에 대한 자세한 설명 및 적용

2024-07-12

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


여기에 이미지 설명을 삽입하세요.


동시 프로그래밍에서는 동기화가 기본 요구 사항입니다. 세마포어는 공유 리소스에 대한 액세스를 제어하는 ​​데 사용되는 일반적인 동기화 메커니즘입니다. C#에서 세마포는 System.Threading 네임스페이스 아래의 Semaphore 클래스를 통해 구현됩니다. 이 기사에서는 C#의 세마포어와 해당 애플리케이션을 자세히 소개합니다.

1. 세마포어란 무엇인가?

세마포어는 공유 리소스에 대한 액세스를 제어하는 ​​데 사용할 수 있는 정수 값입니다. 세마포어는 주로 두 가지 목적으로 사용됩니다.

상호 배타적: 동시에 하나의 스레드만 공유 리소스에 액세스할 수 있는지 확인하십시오.
세다: 특정 수의 스레드가 동시에 공유 리소스에 액세스할 수 있도록 허용합니다.
세마포어는 일반적으로 다음 시나리오에서 사용됩니다.

  • 데이터베이스 연결 수를 제한하는 등 리소스에 대한 동시 액세스를 제한합니다.
  • 생산자-소비자 문제에서 데이터 읽기 및 쓰기를 동기화합니다.
  • 여러 프로세스 간에 공유 리소스에 대한 액세스를 동기화합니다.

2. C#의 세마포어 클래스

C#에서 Semaphore 클래스는 세마포에 대한 기본 작업을 제공합니다. 세마포어를 생성하려면 다음 구문을 사용하십시오.

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

initialCount: 세마포어의 초기 카운트 값으로, 세마포어가 생성되었을 때의 값을 나타냅니다.
maximumCount: 세마포어의 최대 개수 값으로, 세마포어가 도달할 수 있는 최대값을 나타냅니다.

3. 세마포어 사용 예

3.1 세마포어 생성

C#에서는 SemaphoreSlim 클래스를 사용하여 세마포를 만듭니다. 이 클래스는 Semaphore의 동기화 컨텍스트 구현으로, 보다 유연한 비동기 작업을 제공합니다.

System.Threading을 사용하여;

public 클래스 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. wait semaphore.WaitAsync(): 세마포를 비동기적으로 기다립니다.
  2. wait semaphore.ReleaseAsync(): 세마포를 비동기적으로 해제합니다.

이를 통해 세마포어 사용이 더욱 유연해지고 비동기 프로그래밍 모델과 더 잘 통합됩니다.

4. 요약

C#의 세마포(세마포)는 개발자가 공유 리소스에 대한 액세스를 제어하는 ​​데 도움이 될 수 있는 강력한 동기화 메커니즘입니다. 세마포어를 사용하면 공유 리소스에 대한 여러 스레드의 액세스를 효과적으로 관리할 수 있어 리소스 사용으로 인해 데이터 경합이나 기타 동기화 문제가 발생하지 않도록 할 수 있습니다.

C# 프로그래밍에서 세마포어의 중요성은 개발자가 코드 가독성과 유지 관리성을 유지하면서 복잡한 동시성 제어 논리를 구현하는 데 도움을 주는 기능에 반영됩니다. 사용 편의성은 간단한 API 디자인과 풍부한 동기화 컨텍스트 지원에 반영됩니다.

실제 애플리케이션에서는 세마포어를 사용하여 데이터베이스 연결 풀의 크기를 제한하고, 네트워크 리소스에 대한 액세스를 제어하고, 생산자-소비자 모델의 동기화를 달성할 수 있습니다. 이 글의 소개를 통해 독자들이 Semaphore의 원리와 사용법을 더 잘 이해하고 실제 프로젝트에서 활용할 수 있기를 바랍니다.