Мьютекс
Мью́текс (англ. mutex, от mutual exclusion — «взаимное исключение») — аналог одноместного семафора, служащий в программировании для синхронизации одновременно выполняющихся потоков.
Мьютекс отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние. Мьютексы — это один из вариантов семафорных механизмов для организации взаимного исключения. Они реализованы во многих ОС, их основное назначение — организация взаимного исключения для потоков из одного и того же или из разных процессов.
Мьютексы — это простейшие двоичные семафоры, которые могут находиться в одном из двух состояний — отмеченном или неотмеченном (открыт и закрыт соответственно). Когда какой-либо поток, принадлежащий любому процессу, становится владельцем объекта mutex, последний переводится в неотмеченное состояние. Если задача освобождает мьютекс, его состояние становится отмеченным.
Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток блокируется до тех пор, пока мьютекс не будет освобождён.
Цель использования мьютексов — защита данных от повреждения в результате асинхронных изменений (состояние гонки), однако могут порождаться другие проблемы — например взаимная блокировка (клинч).
Содержание
Мьютексы в Win32 API
Win32 API в Windows имеет две реализации мьютексов — собственно мьютексы[1], имеющие имена и доступные для использования между разными процессами, и критические секции[2], которые могут использоваться только в пределах одного процесса. Для каждого из этих двух типов мьютексов используются свои функции захвата и освобождения.
Критическая секция в Windows по возможности блокируется без использования вызова режима ядра (аналогично спинлоку), но при невозможности такой блокировки поток запрашивает ядро.
Мьютексы в Unix-подобных системах
Мьютекс в стандартной библиотеке Pthreads может использоваться в одном процессе или в разных, но в любом случае всем использующим процессам требуется доступ к памяти, в которой он размещён. Такой мьютекс может иметь один из следующих типов[3]:
- PTHREAD_MUTEX_NORMAL — нет контроля повторного захвата тем же потоком (англ. thread);
- PTHREAD_MUTEX_RECURSIVE — повторные захваты тем же потоком допустимы, ведётся счётчик таких захватов;
- PTHREAD_MUTEX_ERRORCHECK — повторные захваты тем же потоком вызывают немедленную ошибку.
Мьютексы в языке Си
Последний стандарт языка Си (ISO/IEC 9899:2011[4]) определяет тип mtx_t и функции для работы с ним, которые должны быть доступны, если макрос __STDC_NO_THREADS__ не был определён компилятором. Семантика и свойства мьютексов в целом совпадают со стандартом POSIX:
- mtx_plain — нет контроля повторного захвата тем же потоком;
- mtx_recursive — повторные захваты тем же потоком допустимы, ведётся счётчик таких захватов;
- mtx_timed — поддерживается захват мьютекса с тайм-аутом (следует отметить, что, в отличие от стандарта POSIX, поддержка этого свойства мьютекса не является опциональной).
Возможность использования мьютексов в разделяемой памяти различных процессов в стандарте Си11 не рассматривается.
Мьютексы в языке C++
Стандарт языка C++ (ISO/IEC 14882:2011[5]) определяет различные классы мьютексов:
- mutex — нет контроля повторного захвата тем же потоком;
- recursive_mutex — повторные захваты тем же потоком допустимы, ведётся счётчик таких захватов;
- timed_mutex — нет контроля повторного захвата тем же потоком, поддерживается захват мьютекса с тайм-аутом;
- recursive_timed_mutex — повторные захваты тем же потоком допустимы, ведётся счётчик таких захватов, поддерживается захват мьютекса с тайм-аутом.
Следует отметить библиотеку Boost, которая обеспечивает:
- реализацию мьютексов, совместимых по интерфейсу со стандартом C++11 для компиляторов и платформ, которые не поддерживают этот стандарт;
- реализацию дополнительных классов мьютексов: shared_mutex и др., которые позволяют захватывать мьютекс для совместного владения несколькими потоками только для чтения данных.
Примечания
- ↑ [msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx Create Mutex]. [www.webcitation.org/65RqR61Sl Архивировано из первоисточника 14 февраля 2012].
- ↑ [msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx Critical sections]. [www.webcitation.org/65RqRkQBx Архивировано из первоисточника 14 февраля 2012].
- ↑ [pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_settype.html pthread_mutexattr_settype(3)]. [www.webcitation.org/65RqSDvim Архивировано из первоисточника 14 февраля 2012].
- ↑ [www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=57853 ISO/IEC 9899:2011 — Information technology — Programming languages — C]
- ↑ ISO, [www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372 ISO/IEC 14882:2011 Information technology — Programming languages — C++]
См. также
- Многопоточность
- Семафор
- Фьютекс, быстрый пользовательский мьютекс
- Спинлок
|
<imagemap>: неверное или отсутствующее изображение |
Для улучшения этой статьи желательно?:
|