Поделиться через


Мьютексы

Объект Mutex можно использовать для получения монопольного доступа к ресурсу. Класс Mutex использует больше системных ресурсов, чем Monitor класс, но его можно маршалировать по границам домена приложения, его можно использовать с несколькими ожиданиями, и его можно использовать для синхронизации потоков в разных процессах. Сравнение механизмов управляемой синхронизации см. в разделе Обзор примитивов синхронизации.

Примеры кода см. в справочной документации по конструкторам Mutex.

Использование мьютексов

Поток вызывает метод WaitOne из мьютекса, чтобы затребовать владение. Вызов блокируется до тех пор, пока мьютекс не будет доступен или пока не истечет дополнительное время ожидания. Если мьютексом не владеет ни один поток, сообщается состояние мьютекса.

Поток освобождает мьютекс, вызывая его метод ReleaseMutex. Мьютексы поддерживают сходство потоков, т. е. мьютекс может быть освобожден только тем потоком, который им владеет. Если поток освобождает мьютекс, которым он не владеет, в потоке создается исключение ApplicationException.

Так как класс Mutex является производным от WaitHandle, вы также можете вызвать статические методы WaitAll или WaitAny объекта WaitHandle, чтобы запросить владение Mutex в сочетании с другими дескрипторами ожидания.

Если поток владеет Mutex, он может указывать этот же Mutex в повторных запросах ожидания, не прерывая выполнение. Но в этом случае, чтобы отказаться от владения, потребуется освободить Mutex столько же раз, сколько он был вызван.

Заброшенные мьютекси

Если поток завершается без освобождения Mutex, мьютекс считается отмененным. Это часто указывает на серьезную ошибку программирования, поскольку ресурс, защищаемый мьютексом, может остаться в несогласованном состоянии. Исключение AbandonedMutexException создается в следующем потоке, который завладеет этим мьютексом.

В случае системного мьютекса брошенный мьютекс может указывать на то, что работа приложения была внезапно прекращена (например, с помощью диспетчера задач Windows).

Локальные и системные мьютексы

Мьютексы бывают двух типов: локальные и именованные системные. Если объект Mutex создается с помощью конструктора, который принимает имя, мьютекс сопоставляется с объектом операционной системы, имеющим это имя. Именованные системные мьютексы доступны во всей операционной системе и могут использоваться для синхронизации действий процессов. Вы можете создать сразу несколько объектов Mutex, представляющих один и тот именованный системный мьютекс, а также открывать именованный системный мьютекс с помощью метода OpenExisting.

Локальный мьютекс существует только в вашем процессе. Его может использовать любой поток в вашем процессе, имеющий ссылку на локальный объект Mutex. Каждый объект Mutex является отдельным локальным мьютексом.

Безопасность управления доступом для системных мьютексов

платформа .NET Framework предоставляет возможность запрашивать и настраивать безопасность управления доступом Windows для именованных системных объектов. Системные мьютексы рекомендуется защищать с момента создания, поскольку системные объекты глобальны, а значит, могут быть заблокированы не вашим кодом.

Сведения о защите и управлении доступом для мьютексов вы найдете в описаниях классов MutexSecurity и MutexAccessRule, перечисления MutexRights, методов GetAccessControl, SetAccessControl и OpenExisting класса Mutex и описании конструктора Mutex(Boolean, String, Boolean, MutexSecurity).

Примечание.

Безопасность управления доступом для системных мьютексов доступна только с платформа .NET Framework, она недоступна в .NET Core или .NET 5+.

См. также