OS2.GURU - Использование семафоров в среде Presentation ManagerOS2.GURU - Использование семафоров в среде Presentation Manager

Welcome to eComStation.RU site!

Select your language: Russian English Deutch Spanish Italian Portuguese Czech Polish French

Frequently asked questions and answers:

eComStation.RU

+7-981-8529467 (Санкт-Петербург)
ru · en · de · es · it · pt · cz · pl · fr
OS/2 - это совершенно другая операционная система для PC (ArcaOS, eComStation, IBM OS/2 Warp)
Программы, новости, статьи, поддержка пользователей, оборудование, вопросы и ответы.
 
      Что такое OS/2?НовостиУстановкаОбновлениеПрименениеБудущееСообществоКупить    
**
(Карта сайта)

 
 
Списки протестированного OS/2 оборудования

 
Обновление

 
Программы

 
(Санкт-Петербург)

 
Преимущества (1)

 
Разработчику (1)

 
(Пайпы программ)

 
Компании: (1)

 
История (1):

 
(Бонусы)

 
Советы:

 
(Барьеры и решения)

 
Технологии: (1)

 
(Применение в науке, лаборатории, ..)

 

 
Готовые решения:

 
Новая eComStation:

 
Будущее: (1)

 
(Ссылки на другие сайты)

 
(Картинка дня)

 
Артефакты OS/2

 
Гаджеты

Обновите ArcaOS до уровня NeoWPS

  • Установите набор PNG иконок, нарисованных дизайнером, специализирующемся на оформлении OS/2
  • Установите eSchemes 2018, чтобы менять цвета и кнопки на рабочем столе

Использование семафоров в среде Presentation Manager


TITLE: Использование семафоров в среде Presentation Manager

DATE: 2010-05-23 21:10:45

AUTHOR: Dmitry A. Steklenev

Что такое мьютекс

Мьютекс (англ. mutex, от mutual exclusion - взаимное исключение) - одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихся потоков. Приложения обычно используют мьютексы для защиты общих ресурсов от одновременного доступа из разных потоков или процессов.

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

Взаимная блокировка

Основная опасность при использовании нескольких мьютексов, это возникновение взаимных блокировок. При возникновении такой блокировки, два потока могут бесконечно ожидать нужный им ресурс. Пользователь при этом имеет одну, а то и более, зависших программ. Простейший пример взаимной блокировки:

  1. Поток 1 успешно захватывает мьютекс A.
  2. Поток 2 успешно захватывает мьютекс B.
  3. Поток 1 ожидает захвата мьютекса B.
  4. Поток 2 ожидает захвата мьютекса A.

Выявление взаимных блокировок при отладке программ является непростой задачей, так как для их возникновения нужны специфические условия одновременного выполнения нескольких потоков. Простейшим способом избежания взаимной блокировки является разработка иерархии мьютексов и захват и освобождение их в одном, строго определенном, порядке. Существует еще ряд приемов борьбы со взаимными блокировками, но их изучение не является целью данной статьи.

Следует отметить, что в OS/2 реализована разновидность мьютексов, уменьшающая вероятность возникновения взаимной блокировки: поток может повторно захватить мьютекс, ранее уже захваченный этим же потоком.

Мьютексы в среде Presentation Manager

Используя мьютексы в среде PM, с большой вероятностью, вы столкнетесь с ситуациями, очень напоминающими взаимную блокировку. Это может происходить даже в том случае, если на все приложение использован один единственный мьютекс. Почему же такое происходит? Для этого сначала необходимо разобраться с механизмом пересылки сообщений между потоками в Presentation Manager.

WinPostMsg и WinSendMsg

В случае с WinPostMsg cообщение кладётся в очередь потока, которому принадлежит окно, являющееся адресатом для данного сообщения. После этого, выполнение потока, пославшего сообщение, продолжается. Отправителю неизвестно, когда посланное сообщение будет обработано и каковы будут результаты этой обработки.

Чтобы как-то разделить посылку сообщения с помощью WinPostMsg от аналогичного действия, выполненного с помощью WinSendMsg, будем называть последнее действие передачей сообщения. Разница между ними примерно такая же, как между посылкой письма по почте и личной передачей его из рук в руки.

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

Что же происходит

Если внимательно прочитать предыдущий абзац, то будет очевидно, что WinSendMsg ведет себя точно так же, как ведут себя мьютексы в OS/2. Возможно, что механизм передачи сообщения в Presentation Manager и реализован с помощью мьютексов. А раз у нас появился дополнительный, нигде не учтенный мьютекс, то могут появиться и неучтенные взаимные блокировки. Простейший пример:

  1. Поток 1 успешно захватывает мьютекс A.
  2. Поток 2 ожидает захвата мьютекса A.
  3. Поток 1 ожидает возможности передачи сообщения в Поток 2.

Как же избежать проблем с мьютексами

Напрашивается простой вывод, что использовать мьютексы в среде PM не стоит. Или нужно очень внимательно следить за тем, чтобы между захватом и освобождением мьютекса не вызывались никакие функции, могущие вызвать передачу сообщений в другие потоки. И то и другое весьма усложняет процесс разработки приложений.

Однако, решение существует. И существует давно. Но почему то, ему уделяется крайне мало внимания. Найти упоминания о нём крайне трудно. Итак, внимание, этим решением является использование функции WinRequestMutexSem.

Отличием этой функции от всем известной DosRequestMutexSem является то, что поток, вставший в ожидание мьютекса с помощью этой функции, может продолжать принимать сообщения, передаваемые другими потоками. Нужно отметить, что принимаются и обрабатываются только сообщения, переданные WinSendMsg. Сообщения, посылаемые WinPostMsg, по прежнему помещаются в очередь сообщений и ожидают своей обработки.

У этой функции есть два недостатка:

  1. Время ожидания, указанное при вызове функции, может не соблюдаться с достаточной точностью. Происходит это потому, что между попытками захватить мьютекс, происходит обработка других сообщений, и время этой обработки может быть различным.
  2. Порядок следования сообщений может частично нарушаться. Т.е. если при обработке сообщения A, поток встал в ожидание мьютекса, то сообщение B, передача которого началась позже, в итоге будет обработано раньше A.

Оба этих недостатка не являются достаточно существенными, чтобы отказаться от преимуществ, которые дает использование WinRequestMutexSem.

Рекомендации

Если разрабатывается приложение или библиотека, предназначенные для работы в среде Presentation Manager, то для захвата семафоров необходимо использовать только вызовы WinRequestMutexSem. Даже в том случае, если на текущий момент использование DosRequestMutexSem является вполне безопасным. Это позволит избежать возможных проблем при дальнейшей модернизации кода. Не следует бояться дополнительных накладных расходов, так как при вызове WinRequestMutexSem из потока, который не имеет очереди сообщений и, следовательно, не может быть получателем сообщений, вызов WinRequestMutexSem будет автоматически преобразован в вызов DosRequestMutexSem.

Необходимо отметить, что Presentation Manager также предоставляет функции WinWaitEventSem и WinWaitMuxWaitSem, являющиеся аналогами функций DosWaitEventSem и DosWaitMuxWaitSem и обладающими теми же замечательными свойствами, что и WinRequestMutexSem.