
Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
32. Мьютексы
Мью?текс (англ. mutex, от mutual exclusion — «взаимное исключение») — одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихсяпотоков.
Мьютексы — это один из вариантов семафорных механизмов для организации взаимного исключения. Они реализованы во многих ОС, их основное назначение — организация взаимного исключения для потоков из одного и того же или из разных процессов.
Мьютексы — это простейшие двоичные семафоры, которые могут находиться в одном из двух состояний — отмеченном или неотмеченном (открыт и закрыт соответственно). Когда какой-либо поток, принадлежащий любому процессу, становится владельцем объекта mutex, последний переводится в неотмеченное состояние. Если задача освобождает мьютекс, его состояние становится отмеченным.
Задача мьютекса — защита объекта от доступа к нему других потоков, отличных от того, который завладел мьютексом. В каждый конкретный момент только один поток может владеть объектом, защищённым мьютексом. Если другому потоку будет нужен доступ к переменной, защищённой мьютексом, то этот поток засыпает до тех пор, пока мьютекс не будет освобождён.
Цель использования мьютексов — защита данных от повреждения в результате асинхронных изменений (состояние гонки), однако могут порождаться другие проблемы — такие, каквзаимная блокировка (клинч).
Мьютекс это одна из реализаций спинлок.
Мьютекс отличается от семафора общего вида тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
Содержание
[убрать]
• 1 Мьютексы в Win32 API
• 2 Мьютексы в Unix-подобных системах
• 3 Мьютексы в языке Си
• 4 Мьютексы в языке C++
• 5 Примечания
• 6 См. также
Мьютексы в 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 и др., которые позволяют захватывать мьютекс для совместного владения несколькими потоками только для чтения данных.
Мьютекс (mutex) - это просто блокировка, используемая для реализации гарантированной исключительности. В частности, в каждый момент времени мьютексом может владеть только один объект. Если какой-то объект хочет получить мьютекс, который уже кто-то занял, он должен дождаться момента его освобождения. В ядре FreeBSD владельцами мьютексов являются процессы.
Мьютексы могут быть затребованы рекурсивно, но предполагается, что они занимаются на короткое время. В частности, владельцу мьютекса нельзя выдерживать паузу. Если вам нужно выполнить блокировку на время паузы, используйте блокировку через lockmgr(9).
Каждый мьютекс имеет несколько представляющих интерес характеристик:
Имя переменной
Имя переменной struct mtx в исходных текстах ядра.
Логическое имя
Имя мьютекса, назначенное ему через mtx_init. Это имя выводится в сообщениях трассировки KTR и диагностических предупреждающих и ошибочных сообщениях и используется для идентификации мьютексов в отладочном коде.
Тип
Тип мьютекса в терминах флагов MTX_*. Значение каждого флага связано с его смыслом так, как это описано в mutex(9).
MTX_DEF
Sleep-мьютекс
MTX_SPIN
Spin-мьютекс
MTX_COLD
Этот мьютекс инициализируется очень рано. Поэтому он должен быть объявлен через функции MUTEX_DECLARE, а флаг MTX_COLD должен быть передан в функцию mtx_init.
MTX_TOPHALF
Этот spin-мьютекс не запрещает прерывания.
MTX_NORECURSE
Этот мьютекс не разрешается блокировать рекурсивно.
Защиты
Список структур данных или членов структур данных, которые защищает этот мьютекс. Для членов структур данных иям будет в форме имя структуры.имя члена структуры.
Зависимые функции
Функции, которые можно вызвать, если этот мьютекс занят.
Table 7-1. Список мьютексов
Имя переменной Логическое имя Тип Защиты Зависимые функции
sched_lock "sched lock" MTX_SPIN|MTX_COLD _gmonparam, cnt.v_swtch, cp_time, curpriority, mtx.mtx_blocked, mtx.mtx_contested, proc.p_contested,proc.p_blocked, proc.p_flag (P_PROFIL XXX, P_INMEM, P_SINTR, P_TIMEOUT, P_SWAPINREQ XXX, P_INMENXXX), proc.p_nice, proc.p_procq, proc.p_blocked, proc.p_estcpu, proc.p_nativepri, proc.p_priority,proc.p_usrpri, proc.p_rtprio, proc.p_rqindex, proc.p_stats->p_prof, proc.p_stats->p_ru, proc.p_stat,proc.p_cpticks proc.p_iticks, proc.p_uticks, proc.p_sticks, proc.p_swtime, proc.p_slptime, proc.p_runtime,proc.p_pctcpu, proc.p_oncpu, proc.p_asleep, proc.p_wchan, proc.p_wmesg, proc.p_slpq, proc.p_vmspace (XXX - в statclock), pscnt, slpque, itqueuebits, itqueues, rtqueuebits, rtqueues, queuebits, queues,idqueuebits, idqueues, switchtime, setrunqueue,remrunqueue,mi_switch,chooseproc,schedclock,resetpriority,updatepri,maybe_resched,cpu_switch,cpu_throw
vm86pcb_lock "vm86pcb lock" MTX_DEF |MTX_COLD vm86pcb vm86_bioscall
Giant "Giant" MTX_DEF |MTX_COLD nearly everything lots
callout_lock "callout lock" MTX_SPIN callfree, callwheel, nextsoftcheck, proc.p_itcallout, proc.p_slpcallout, softticks, ticks
Соседние файлы в папке Smirnov