Sobes.tech
Middle
161
questionbank

Что такое мьютекс и для чего он используется?

Answer from AI

sobes.tech AI

Мьютекс (mutex, mutual exclusion) — это примитив синхронизации потоков, который позволяет только одному потоку в данный момент времени получить доступ к разделяемому ресурсу или критической секции кода. Используется для предотвращения состояния гонки (race condition), когда несколько потоков пытаются одновременно изменить один и тот же ресурс, что может привести к некорректным данным.

Основные операции с мьютексом: WaitOne (или Aquire) для захвата мьютекса и ReleaseMutex (или Release) для его освобождения.

Пример использования мьютекса:

using System;
using System.Threading;

public class SharedResource
{
    private static Mutex mutex = new Mutex();
    private static int counter = 0;

    public static void IncrementCounter()
    {
        mutex.WaitOne(); // Захватываем мьютекс
        try
        {
            // Критическая секция
            Console.WriteLine($"Поток {Thread.CurrentThread.ManagedThreadId} захватил мьютекс. Счетчик: {counter}");
            counter++;
            Thread.Sleep(100); // Имитация работы
        }
        finally
        {
            mutex.ReleaseMutex(); // Освобождаем мьютекс
            Console.WriteLine($"Поток {Thread.CurrentThread.ManagedThreadId} освободил мьютекс. Счетчик: {counter}");
        }
    }

    public static void Main(string[] args)
    {
        Thread[] threads = new Thread[5];
        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new Thread(IncrementCounter);
            threads[i].Start();
        }

        foreach (Thread thread in threads)
        {
            thread.Join();
        }

        Console.WriteLine($"Финальное значение счетчика: {counter}");
    }
}

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

// Создание именованного мьютекса (для межпроцессной синхронизации)
Mutex namedMutex = new Mutex(false, "MyNamedMutex");

Мьютекс имеет владельца (поток, который его захватил) и может быть освобожден только этим потоком. Это отличает его от семафора, который может быть освобожден любым потоком.