Compartir tecnología

Explicación detallada y aplicación de Semaphore (semáforo) en C#

2024-07-12

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


Insertar descripción de la imagen aquí


En la programación concurrente, la sincronización es un requisito básico. El semáforo es un mecanismo de sincronización común que se utiliza para controlar el acceso a recursos compartidos. En C#, los semáforos se implementan a través de la clase Semaphore en el espacio de nombres System.Threading. Este artículo presentará en detalle Semaphore y sus aplicaciones en C#.

1. ¿Qué es un semáforo?

Un semáforo es un valor entero que se puede utilizar para controlar el acceso a un recurso compartido. Los semáforos se utilizan principalmente para dos propósitos:

Mutuamente excluyentes: Asegúrese de que solo un subproceso pueda acceder a los recursos compartidos al mismo tiempo.
contar: Permitir que una cierta cantidad de subprocesos accedan a recursos compartidos simultáneamente.
Los semáforos se suelen utilizar en los siguientes escenarios:

  • Limite el acceso simultáneo a los recursos, como limitar el número de conexiones de bases de datos.
  • Sincronizar la lectura y escritura de datos en un problema productor-consumidor.
  • Sincronice el acceso a recursos compartidos entre múltiples procesos.

2. Clase de semáforo en C#

En C#, la clase Semaphore proporciona operaciones básicas con semáforos. Para crear un semáforo, utilice la siguiente sintaxis:

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

inicialCount: el valor de recuento inicial del semáforo, que indica el valor del semáforo cuando se creó.
MaximumCount: el valor de recuento máximo del semáforo, que indica el valor máximo que puede alcanzar el semáforo.

3. Ejemplos de uso de semáforos

3.1 Crear un semáforo

En C#, cree un semáforo usando la clase SemaphoreSlim. Esta clase es una implementación de contexto de sincronización de Semaphore, que proporciona operaciones asincrónicas más flexibles.

utilizando System.Threading;

Clase pública SemaphoreExample
{
private SemaphoreSlim semaphore = new SemaphoreSlim(3); // Crea un semáforo de conteo para permitir el acceso de 3 subprocesos al mismo tiempo

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 Utilice semáforos para sincronizar hilos

El siguiente es un ejemplo sencillo para demostrar cómo crear, obtener y liberar recursos de semáforo.

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

En este ejemplo, creamos un semáforo que permite que hasta 3 subprocesos ejecuten el método Work simultáneamente. Cada hilo intenta obtener el semáforo cuando llama a semaphore.WaitOne(). Si el valor del semáforo es mayor que 0, el hilo continuará ejecutándose. De lo contrario, el hilo se bloqueará hasta que otro hilo libere el semáforo.

Operaciones asincrónicas
La clase SemaphoreSlim también proporciona métodos asincrónicos de espera y liberación:

  1. await semaphore.WaitAsync(): espera asincrónicamente el semáforo
  2. await semaphore.ReleaseAsync(): libera el semáforo de forma asincrónica

Esto hace que el uso de semáforos sea más flexible y esté mejor integrado con los modelos de programación asincrónica.

4. Resumen

El semáforo (semaphore) en C# es un poderoso mecanismo de sincronización que puede ayudar a los desarrolladores a controlar el acceso a los recursos compartidos. Al utilizar semáforos, podemos gestionar eficazmente el acceso de múltiples subprocesos a recursos compartidos, garantizando que el uso de recursos no provoque carreras de datos u otros problemas de sincronización.

La importancia de Semaphore en la programación de C# se refleja en su capacidad para ayudar a los desarrolladores a implementar una lógica de control de concurrencia compleja manteniendo al mismo tiempo la legibilidad y el mantenimiento del código. Su facilidad de uso se refleja en su diseño API simple y su rico soporte de contexto de sincronización.

En aplicaciones prácticas, los semáforos se pueden utilizar para limitar el tamaño del grupo de conexiones de la base de datos, controlar el acceso a los recursos de la red y lograr la sincronización del modelo productor-consumidor, etc. A través de la introducción de este artículo, esperamos que los lectores puedan comprender mejor los principios y el uso de Semaphore y aprovecharlos en proyectos reales.