Semaphore – классический семафор, использующий ядро операционной системы для синхронизации потоков. SemaphoreSlim – более лёгкая и быстрая версия, работающая в основном на уровне управляемого кода без вызовов ядра ОС. 🚩Когда использовать `Semaphore`, а когда `SemaphoreSlim`?
Используйте
Semaphore, если: Вам нужно разделение ресурсов между разными процессами.
Вы работаете с нативным кодом или сторонними API, использующими семафоры ОС.
Используйте
SemaphoreSlim, если: Вам нужна быстрая блокировка между потоками в одном процессе.
Вы хотите использовать асинхронный код (
async/await). Вам важна производительность.
🚩Пример использования `Semaphore` (между процессами и потоками)
using System;
using System.Threading;
class Program
{
static Semaphore semaphore = new Semaphore(2, 2); // Макс. 2 потока могут войти одновременно
static void Main()
{
for (int i = 1; i <= 5; i++)
{
new Thread(DoWork).Start(i);
}
}
static void DoWork(object id)
{
Console.WriteLine($"Поток {id} ждёт семафор...");
semaphore.WaitOne(); // Захватываем семафор
Console.WriteLine($"Поток {id} выполняет работу...");
Thread.Sleep(2000); // Симуляция работы
Console.WriteLine($"Поток {id} освобождает семафор");
semaphore.Release(); // Освобождаем семафор
}
}
🚩Пример использования `SemaphoreSlim` (быстрее, поддерживает `async/await`)
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2); // 2 потока одновременно
static async Task Main()
{
Task[] tasks = new Task[5];
for (int i = 0; i < 5; i++)
{
tasks[i] = DoWork(i);
}
await Task.WhenAll(tasks);
}
static async Task DoWork(int id)
{
Console.WriteLine($"Задача {id} ждёт семафор...");
await semaphoreSlim.WaitAsync(); // Асинхронное ожидание
Console.WriteLine($"Задача {id} выполняет работу...");
await Task.Delay(2000); // Симуляция работы
Console.WriteLine($"Задача {id} освобождает семафор");
semaphoreSlim.Release(); // Освобождаем семафор
}
}
Ставь 👍 и забирай 📚 Базу знаний