Составители:
Рубрика:
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 компоненты из других процессов с режимом «копирование при записи». нет. Основные механизмы взаимодействия процессов могут быть разде- лены на несколько групп:
Страницы
- « первая
- ‹ предыдущая
- …
- 126
- 127
- 128
- 129
- 130
- …
- следующая ›
- последняя »