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

UptoLike

7.2.1.4. Ожидающие таймеры
Эти объекты предназначены для выполнения операций через задан-
ные промежутки времени или в заданное время. Таймеры бывают перио-
дическими или однократными, также их разделяют на таймеры с ручным
сбросом и синхронизирующие:
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
hTimer = CreateWaitableTimer(NULL, TRUE, “WaitableTimer”);
/* задать срабатывание через 5 секунд */
liDueTime.QuadPart=-50000000;
SetWaitableTimer( hTimer, &liDueTime, 0, NULL, NULL, 0 );
WaitForSingleObject( hTimer, INFINITE );
return 0;
}
Таймеры могут служить в качестве синхронизирующих объектов, как
в данном примере, а могут вызывать указанную разработчиком функцию,
если поток в нужное время находится в ожидании оповещения.
Следует подчеркнуть, что ожидающие таймеры обладают ограничен-
ной точностью работы. При необходимости точно планировать время вы-
полнения (например, в случае обработки потоков мультимедиа данных) на-
до использовать специальный таймер, предназначенный для работы с муль-
тимедиа (см. функции timeGetSystemTime, timeBeginPeriod и др.).
7.2.2 Процессы
Процессы в Windows определяют адресное пространство, которое бу-
дет использоваться всеми потоками, работающими в этом процессе. В от-
личие от UNIX-подобных систем системного вызова типа fork в Windows
не предусмотрено – новый процесс создается заново, с выделением для
него адресного пространства, проецирования на него компонент системы,
образа исполняемого файла, необходимых динамических библиотек и
других компонент. Эта операция требует чуть больше ресурсов, чем в
UNIX-подобных системах, однако выполняется достаточно быстро – дис-
петчер памяти позволяет просто проецировать на адресное пространство
компоненты из других процессов с режимом «копирование при записи».
Основные механизмы взаимодействия процессов могут быть разде-
лены на несколько групп:
Разработка параллельных приложений для ОС Windows
243
int main( void )
{
unsigned id;
HANDLE hMutex, hThread;
hMutex = CreateMutex( DEFAULT_SECURITY, TRUE, NULL );
hThread = (HANDLE)_beginthreadex(
(void*)0, 0, TProc, (void*)hMutex, 0, &id
);
Sleep( 1000 );
ReleaseMutex( hMutex );
WaitForSingleObject( hThread, INFINITE );
CloseHandle( hThread );
CloseHandle( hMutex );
return 0;
}
ОС Windows предоставляет достаточно удобный набор объектов,
пригодных для синхронизации. Однако, в большинстве случаев эти объе-
кты эффективны с точки зрения операционной системы, представляя са-
мые базовые примитивы. В реальных задачах часто возникают ситуации,
когда необходимо создавать на основе этих примитивов более сложные
составные синхронизирующие объекты. Достаточно распространенными
примерами таких задач являются задачи с барьерной синхронизацией или
задачи с множественным доступом к ресурсу по чтению и исключитель-
ным доступом по записи.
При реализации барьерной синхронизации надо обеспечить не толь-
ко возможность проконтролировать достижение барьера всеми потоками,
но также снова «поставить барьер» сразу после того, как потоки начнут
свое выполнение (иначе какой-либо поток может быстро справиться со
своей работой и снова придет к барьеру, пока тот еще открыт). При этом
потоки, прошедшие барьер, могут начинать свое выполнение со значи-
тельной задержкой.
Синхронизирующие объекты, обслуживающие ресурс с множествен-
ным доступом по чтению и исключительным по записи, должны отслежи-
вать число потоков, осуществляющих чтение данного ресурса, и потоки,
требующие изменения ресурса. Реализация такого объекта должна преду-
сматривать работу в условиях высокой нагрузки – когда несколько потоков
могут одновременно считывать ресурс и при этом не возникает пауз, когда
ресурс является свободным; при этом к тому же ресурсу должны обращать-
ся изменяющие его потоки, требуя при этом исключительного доступа.
Стандартных типов объектов, решающих такие задачи, в Windows
нет.
242
CIL и системное программирование в Microsoft .NET
242                        CIL и системное программирование в Microsoft .NET   Разработка параллельных приложений для ОС Windows                  243


     int main( void )                                                          7.2.1.4. Ожидающие таймеры
     {                                                                              Эти объекты предназначены для выполнения операций через задан-
       unsigned id;                                                            ные промежутки времени или в заданное время. Таймеры бывают перио-
       HANDLE     hMutex, hThread;                                             дическими или однократными, также их разделяют на таймеры с ручным
       hMutex = CreateMutex( DEFAULT_SECURITY, TRUE, NULL );                   сбросом и синхронизирующие:
       hThread = (HANDLE)_beginthreadex(
          (void*)0, 0, TProc, (void*)hMutex, 0, &id                                 #include 
       );                                                                           #include 
       Sleep( 1000 );
       ReleaseMutex( hMutex );                                                      int main()
       WaitForSingleObject( hThread, INFINITE );                                    {
       CloseHandle( hThread );                                                        HANDLE           hTimer = NULL;
       CloseHandle( hMutex );                                                         LARGE_INTEGER    liDueTime;
       return 0;                                                                      hTimer = CreateWaitableTimer(NULL, TRUE, “WaitableTimer”);
     }                                                                                /* задать срабатывание через 5 секунд */
     ОС Windows предоставляет достаточно удобный набор объектов,                      liDueTime.QuadPart=-50000000;
пригодных для синхронизации. Однако, в большинстве случаев эти объе-                  SetWaitableTimer( hTimer, &liDueTime, 0, NULL, NULL, 0 );
кты эффективны с точки зрения операционной системы, представляя са-                   WaitForSingleObject( hTimer, INFINITE );
мые базовые примитивы. В реальных задачах часто возникают ситуации,                   return 0;
когда необходимо создавать на основе этих примитивов более сложные                  }
составные синхронизирующие объекты. Достаточно распространенными                    Таймеры могут служить в качестве синхронизирующих объектов, как
примерами таких задач являются задачи с барьерной синхронизацией или           в данном примере, а могут вызывать указанную разработчиком функцию,
задачи с множественным доступом к ресурсу по чтению и исключитель-             если поток в нужное время находится в ожидании оповещения.
ным доступом по записи.                                                             Следует подчеркнуть, что ожидающие таймеры обладают ограничен-
     При реализации барьерной синхронизации надо обеспечить не толь-           ной точностью работы. При необходимости точно планировать время вы-
ко возможность проконтролировать достижение барьера всеми потоками,            полнения (например, в случае обработки потоков мультимедиа данных) на-
но также снова «поставить барьер» сразу после того, как потоки начнут          до использовать специальный таймер, предназначенный для работы с муль-
свое выполнение (иначе какой-либо поток может быстро справиться со             тимедиа (см. функции timeGetSystemTime, timeBeginPeriod и др.).
своей работой и снова придет к барьеру, пока тот еще открыт). При этом
потоки, прошедшие барьер, могут начинать свое выполнение со значи-             7.2.2 Процессы
тельной задержкой.                                                                  Процессы в Windows определяют адресное пространство, которое бу-
     Синхронизирующие объекты, обслуживающие ресурс с множествен-              дет использоваться всеми потоками, работающими в этом процессе. В от-
ным доступом по чтению и исключительным по записи, должны отслежи-             личие от UNIX-подобных систем системного вызова типа fork в Windows
вать число потоков, осуществляющих чтение данного ресурса, и потоки,           не предусмотрено – новый процесс создается заново, с выделением для
требующие изменения ресурса. Реализация такого объекта должна преду-           него адресного пространства, проецирования на него компонент системы,
сматривать работу в условиях высокой нагрузки – когда несколько потоков        образа исполняемого файла, необходимых динамических библиотек и
могут одновременно считывать ресурс и при этом не возникает пауз, когда        других компонент. Эта операция требует чуть больше ресурсов, чем в
ресурс является свободным; при этом к тому же ресурсу должны обращать-         UNIX-подобных системах, однако выполняется достаточно быстро – дис-
ся изменяющие его потоки, требуя при этом исключительного доступа.             петчер памяти позволяет просто проецировать на адресное пространство
     Стандартных типов объектов, решающих такие задачи, в Windows              компоненты из других процессов с режимом «копирование при записи».
нет.                                                                                Основные механизмы взаимодействия процессов могут быть разде-
                                                                               лены на несколько групп: