Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 125 стр.

UptoLike

веряют состояние ожидаемого объекта или ожидаемых объектов и продол-
жают выполнение, только если объекты свободны. В зависимости от типа
ожидаемого объекта, система может предпринять специальные действия
(например, как только поток дожидается освобождения объекта исключи-
тельного владения, он сразу должен захватить его).
Функция WaitForSingleObject осуществляет ожидание одного объек-
та, а функция WaitForMultipleObjects может ожидать как освобождения
любого из указанных объектов (bWaitAll = FALSE), так и всех сразу
(bWaitAll = TRUE). Ожидание завершается либо по освобождении объек-
та(ов), либо по истечении указанного интервала времени (dwMsecs) в мил-
лисекундах (бесконечное при dwMsecs = INFINITE). Код возврата функции
позволяет определить причину – таймаут, освобождение конкретного объ-
екта либо ошибка.
Если функция WaitForMultipleObjects (или ее клон) ожидает сразу
все объекты группы, то до освобождения всех ожидаемых объектов одно-
временно никаких мер по занятию ранее освободившихся объектов функ-
ция не предпринимает.
В тех случаях, когда поток переходит в состояние ожидания, его ис-
полнение блокируется до конца ожидания. Для реализации APC (и функ-
ций завершения ввода-вывода) необходимо было предусмотреть в опера-
ционной системе возможность приостановки потока с вызовом асинхрон-
ных процедур. Это связано с тем, что система должна гарантировать вы-
полнение функций в контексте конкретного потока для соблюдения норм
безопасности. Ожидание оповещения – это такое состояние ожидания,
которое может быть завершено либо по достижении таймаута, либо при
освобождении указанного объекта, либо после обработки APC. При этом
в контексте потока, находящегося в состоянии ожидания оповещения, об-
рабатывается APC вызов и только затем завершается состояние ожидания.
Для перехода в ожидание оповещения предусмотрены функции
SleepEx, WaitForMultipleObjectsEx, WaitForSingleObjectEx и
SignalObjectAndWait.
Еще несколько функций предназначены для разработки GUI-прило-
жений Win32: MsgWaitForMultipleObjects и MsgWaitForMultipleObjectsEx
выполняют ожидание указанных объектов и, кроме того, могут контроли-
ровать состояние очереди потока, предназначенной для обработки окон-
ных сообщений. Функция WaitForInputIdle ожидает, пока GUI-приложе-
ние не закончит свою инициализацию и не перейдет в ожидание в цикле
обработки сообщений.
Несколько типов объектов в Win32 предназначены только для взаим-
ной синхронизации потоков: события (event), семафоры (semaphore), объек-
ты исключительного владения (мьютексы, mutex, mutual exclusion) и ожида-
ющие таймеры (waitable timer). Для изменения их состояния предусмотре-
Разработка параллельных приложений для ОС Windows
237
for ( errs=i=0; i<ASIZE; i++ )
if ( array[i] != THREADS ) errs++;
if ( errs ) printf(“Detected %d errors!\n”, errs );
DeleteCriticalSection( &CS );
return 0;
}
Помимо этих основных функций, Windows предоставляет еще
несколько, например, TryEnterCriticalSection, которая позволяет при не-
обходимости не входить в секцию, если она занята (так как при использо-
вани EnterCriticalSection ожидание будет неограниченным по времени,
что может быть неприемлемым).
Кроме того, эффективность критических секций на многопроцессор-
ных машинах может быть повышена, если перед началом ожидания занятой
секции, вместо перехода к ожиданию в режиме ядра, выполнить предвари-
тельный кратковременный цикл с опросом состояния секции. Если секция
занимается другим потоком на небольшое время, то такой цикл позволяет
дождаться ее освобождения, не переходя в режим ядра. Для этого предна-
значены функции: InitializeCriticalSectionAndSpinCount и
SetCriticalSectionSpinCount. Они позволяют задавать число опросов состо-
яния занятой критической секции перед переходом в режим ядра для ожи-
дания. На однопроцессорных машинах опросы не выполняются и функция
InitializeCriticalSectionAndSpinCount ничем не отличается от обычной
функции InitializeCriticalSection.
7.2.1.3. Синхронизация с использованием объектов ядра
В Windows для синхронизации используются самые разные объекты,
применение которых существенно различается. Однако при рассмотрении
синхронизации особое положение имеет момент перехода ожидаемого
объекта в свободное состояние – с точки зрения ожидающего потока со-
вершенно неважно, какие события привели к этому и какой именно объ-
ект стал свободным. Поэтому при большом разнообразии объектов, при-
годных для синхронизации, существует всего несколько основных функ-
ций, осуществляющих ожидание объекта ядра:
DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMsecs );
DWORD WaitForMultipleObjects(
DWORD nCount, const HANDLE* lpHandles,
BOOL bWaitAll, DWORD dwMsecs
);
С точки зрения операционной системы объекты ядра, поддерживаю-
щие интерфейс синхронизируемых объектов, могут находиться в одном из
двух состояний: свободном (signaled) и занятом (nonsignaled). Функции про-
236
CIL и системное программирование в Microsoft .NET
236                          CIL и системное программирование в Microsoft .NET   Разработка параллельных приложений для ОС Windows                    237


       for ( errs=i=0; i