MessageDisplay(&mblock);
mblock.nCons++;
mblock.nLost = mblock.sequence – mblock.nCons;
mblock.f_ready = 0; /* Новые готовые сообщения отсутствуют. */
} __finally { ReleaseMutex (mblock.mguard); }
} else {
_tprintf(_T("Недопустимая команда. Повторите попытку.\n"));
}
}
return 0;
}
Примечание
Существует вероятность того, что поток потребителя, уведомленный о готовности сообщения, в действительности не успеет обработать текущее сообщение до того, как поток производителя сгенерирует еще одно сообщение до захвата мьютекса потоком потребителя. В результате такого поведения программы поток потребителя может обработать одно и то же сообщение дважды, если бы не проверка, предусмотренная в начале try-блока потребителя. Эта и другие аналогичные проблемы обсуждаются в главе 10.
Обзор: объекты синхронизации Windows
Наиболее важные свойства объектов синхронизации Windows перечислены в табл. 8.2.
Таблица 8.2. Сравнительные характеристики объектов синхронизации Windows
CRITICAL_SECTION | Мьютекс | Семафор | Событие | |
---|---|---|---|---|
Именованный защищаемый объект синхронизации | Нет | Да | Да | Да |
Доступность из нескольких процессов | Нет | Да | Да | Да |
Синхронизация | Вхождение | Ожидание | Ожидание | Ожидание |
Освобождение | Выход | Мьютекс может быть освобожден или оставлен без контроля. | Освобождается любым потоком. | Функции SetEvent, PulseEvent. |
Права владения | В каждый момент времени иметь права владельца может только один поток. Владеющий поток может осуществлять вхождение несколько раз, не блокируя свое выполнение. | В каждый момент времени иметь права владельца может только один поток. Владеющий поток может выполнять функцию ожидания несколько раз, не блокируя свое выполнение. | Понятие владения неприменимо. Доступ разрешен одновременно нескольким потокам, число которых ограничено максимальным значением счетчика. | Понятие владения неприменимо. Функции SetEvent и PulseEvent могут быть вызваны любым потоком. |
Результат освобождения | Разрешается вхождение одного потока из числа ожидающих. | Вслед за последним освобождением права владения разрешается приобрести одному потоку из числа ожидающих. | Продолжать выполнение могут несколько потоков, число которых определяется текущим значением счетчика. | После вызова функций SetEvent или PulseEvent продолжать выполнение будет один или несколько ожидающих потоков. |
Ожидание сообщений и объектов
Функция MsgWaitForMultipleObjects аналогична функции WaitForMultipleObjects. Применяйте ее для того, чтобы разрешить потоку или процессу обработку событий пользовательского интерфейса, таких как щелчки мышью, во время ожидания перехода объектов синхронизации в сигнальное состояние.
Дополнительные рекомендации относительно использования мьютексов и объектов CRITICAL_SECTION