Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание эффективных приложений для Windows Джеффри Рихтер 2004 (Книга).pdf
Скачиваний:
377
Добавлен:
15.06.2014
Размер:
8.44 Mб
Скачать

...

SetEvent(hEventWorkerThreadDone);

WaitForSingleObject(hEventMoreWorkToBeDone, INFINITE);

// выполняем еще какие-то операции

...

Этот фрагмент кода выполняется рабочим потоком, который проделывает какие то операции, а затем вызывает SetEvent, чтобы сообщить (другому потоку) об оконча нии своих операций. В то же время в другом потоке имеется код:

WaitForSingleObject(hEventWorkerTnreadDone);

PulseEvent(hEventMoreWorkToBeDone);

Приведенный ранее фрагмент кода рабочего потока порочен по самой своей сути, так как будет работать ненадежно. Ведь вполне вероятно, что после того, как рабо чий поток обратится к SetEvent, немедленно пробудится другой поток и вызовет Pulse Event. Проблема здесь в том, что рабочий поток уже вытеснен и пока еще не получил шанса на возврат из вызова SetEvent, не говоря уж о вызове WaitForSingleObject. В ито

ге рабочий поток не сможет своевременно освободить событие bEventMoreWork ToBeDone

Но если Вы перепишете код рабочего потока с использованием функции Signal ObjectAndWait

// выполняем какие-то операции

SignalObjectAndWait(hEventWorkerThreadDone, hEventMoreWorkToBflDonc, INFINITE, FALSE);

// выполняем еще какие-то операции

то код будет работать надежно, поскольку освобождение и ожидание реализуются на уровне атомарного доступа. И когда пробудичся другой поток, Вы сможете быть аб солютно уверены, что рабочий поток ждет события hEventMoreWorkToBeDone, а зна чит, он обязательно заметит импульс, «приложенный" к событию.

WINDOWS 98

В Windows 98 функция SignalObjectAndWait определена, но не реализована.

ГЛАВА 10 Полезные средства для синхронизации потоков

Зa годы своей практики я часто сталкивался с проблемами синхронизации потоков и поэтому написал ряд С++-классов и компонентов, которыми я поделюсь с Вами в этой главе. Надеюсь, этот код Вам пригодится и сэкономит массу времени при разра ботке приложений — или по крайней мере чему-нибудь научит.

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