Reviews / articles about OS/2 |
Operating systems: ArcaOS, eComStation, IBM OS/2 Warp |
|
|
DATE: 2010-05-23 21:10:45 AUTHOR: Dmitry A. Steklenev
Что такое мьютексМьютекс (англ. mutex, от mutual exclusion - взаимное исключение) - одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихся потоков. Приложения обычно используют мьютексы для защиты общих ресурсов от одновременного доступа из разных потоков или процессов. Мьютексы являются гораздо более быстрым решением по сравнению с другими способами синхронизации доступа к общим ресурсам. Так, поток переводится в состоянии ожидания только в том случае, если мьютекс уже захвачен другим потоком. Это является главным преимуществом мьютексов перед критическими секциями. Т.к. при выполнении последних, в состояние ожидания переводятся все другие потоки текущего процесса, даже если в данный момент времени им вовсе и не нужен доступ к общему ресурсу. Также отсутствует необходимость ждать завершения выполнения предыдущего запроса, который опять же может быть и не связан с доступом к общему ресурсу, как это происходит в случае использования для синхронизации каких либо очередей.
Взаимная блокировкаОсновная опасность при использовании нескольких мьютексов, это возникновение взаимных блокировок. При возникновении такой блокировки, два потока могут бесконечно ожидать нужный им ресурс. Пользователь при этом имеет одну, а то и более, зависших программ. Простейший пример взаимной блокировки:
Выявление взаимных блокировок при отладке программ является непростой задачей, так как для их возникновения нужны специфические условия одновременного выполнения нескольких потоков. Простейшим способом избежания взаимной блокировки является разработка иерархии мьютексов и захват и освобождение их в одном, строго определенном, порядке. Существует еще ряд приемов борьбы со взаимными блокировками, но их изучение не является целью данной статьи. Следует отметить, что в OS/2 реализована разновидность мьютексов, уменьшающая вероятность возникновения взаимной блокировки: поток может повторно захватить мьютекс, ранее уже захваченный этим же потоком.
Мьютексы в среде Presentation ManagerИспользуя мьютексы в среде PM, с большой вероятностью, вы столкнетесь с ситуациями, очень напоминающими взаимную блокировку. Это может происходить даже в том случае, если на все приложение использован один единственный мьютекс. Почему же такое происходит? Для этого сначала необходимо разобраться с механизмом пересылки сообщений между потоками в Presentation Manager.
WinPostMsg и WinSendMsgВ случае с WinPostMsg cообщение кладётся в очередь потока, которому принадлежит окно, являющееся адресатом для данного сообщения. После этого, выполнение потока, пославшего сообщение, продолжается. Отправителю неизвестно, когда посланное сообщение будет обработано и каковы будут результаты этой обработки. Чтобы как-то разделить посылку сообщения с помощью WinPostMsg от аналогичного действия, выполненного с помощью WinSendMsg, будем называть последнее действие передачей сообщения. Разница между ними примерно такая же, как между посылкой письма по почте и личной передачей его из рук в руки. В случае передачи сообщения, выполнение передающего потока останавливается до тех пор, пока сообщение не будет обработано получателем. После обработки сообщения, результат обработки возвращается передающему потоку и его выполнение возобновляется. Следует отметить, что если окно, являющееся адресатом для сообщения, принадлежит тому же самому передающему потоку, то будет произведен прямой вызов функции обработки сообщений для этого окна. В случае же, если окно находится в другом потоке и этот поток в текущий момент занят обработкой другого сообщения (руки у получателя уже заняты), передающий поток будет ожидать до тех пор, пока эта обработка не завершится. И только после этого произойдет передача сообщения получателю.
Что же происходитЕсли внимательно прочитать предыдущий абзац, то будет очевидно, что WinSendMsg ведет себя точно так же, как ведут себя мьютексы в OS/2. Возможно, что механизм передачи сообщения в Presentation Manager и реализован с помощью мьютексов. А раз у нас появился дополнительный, нигде не учтенный мьютекс, то могут появиться и неучтенные взаимные блокировки. Простейший пример:
Как же избежать проблем с мьютексамиНапрашивается простой вывод, что использовать мьютексы в среде PM не стоит. Или нужно очень внимательно следить за тем, чтобы между захватом и освобождением мьютекса не вызывались никакие функции, могущие вызвать передачу сообщений в другие потоки. И то и другое весьма усложняет процесс разработки приложений. Однако, решение существует. И существует давно. Но почему то, ему уделяется крайне мало внимания. Найти упоминания о нём крайне трудно. Итак, внимание, этим решением является использование функции WinRequestMutexSem. Отличием этой функции от всем известной DosRequestMutexSem является то, что поток, вставший в ожидание мьютекса с помощью этой функции, может продолжать принимать сообщения, передаваемые другими потоками. Нужно отметить, что принимаются и обрабатываются только сообщения, переданные WinSendMsg. Сообщения, посылаемые WinPostMsg, по прежнему помещаются в очередь сообщений и ожидают своей обработки. У этой функции есть два недостатка:
Оба этих недостатка не являются достаточно существенными, чтобы отказаться от преимуществ, которые дает использование WinRequestMutexSem.
РекомендацииЕсли разрабатывается приложение или библиотека, предназначенные для работы в среде Presentation Manager, то для захвата семафоров необходимо использовать только вызовы WinRequestMutexSem. Даже в том случае, если на текущий момент использование DosRequestMutexSem является вполне безопасным. Это позволит избежать возможных проблем при дальнейшей модернизации кода. Не следует бояться дополнительных накладных расходов, так как при вызове WinRequestMutexSem из потока, который не имеет очереди сообщений и, следовательно, не может быть получателем сообщений, вызов WinRequestMutexSem будет автоматически преобразован в вызов DosRequestMutexSem. Необходимо отметить, что Presentation Manager также предоставляет функции WinWaitEventSem и WinWaitMuxWaitSem, являющиеся аналогами функций DosWaitEventSem и DosWaitMuxWaitSem и обладающими теми же замечательными свойствами, что и WinRequestMutexSem.
Комментарии:
|
|
|||||||||||||||||||||||
(C) OS2.GURU 2001-2021