Составители:
Рубрика:
К сожалению, средств для проверки текущего значения счетчика без
изменения состояния семафора нет: функция ReleaseSemaphore позволяет
узнать предыдущее значение, но при этом обязательно увеличит его зна-
чение хотя бы на 1 (попытка увеличить на 0 или на отрицательную вели-
чину рассматривается как ошибка), а ожидающая функция обязательно
уменьшит счетчик, если семафор был свободен. Поэтому для определения
значения счетчика надо использовать что-то вроде приведенного ниже
примера:
LONG lCounter;
lCounter = 0;
if ( WaitForSingleObject( hSem, 0 ) == WAIT_OBJECT_0 )
ReleaseSemaphore( hSem, 1, &lCounter );
/* теперь переменная lCounter содержит значение счетчика */
Семафоры предназначены для ограничения числа потоков, имею-
щих одновременный доступ к какому-либо ресурсу.
Мьютексы
Объекты исключительного владения могут быть использованы в од-
но время не более чем одним потоком. В этом отношении мьютексы по-
добны критическим секциям, с той оговоркой, что работа с ними выпол-
няется в режиме ядра (при использовании критических секций переход в
режим ядра необязателен) и что мьютексы могут быть использованы для
межпроцессного взаимодействия, тогда как критические секции реализо-
ваны для применения внутри процесса.
Для захвата мьютекса используется ожидающая функция WaitFor..., а
для освобождения – функция ReleaseMutex. При создании мьютекса функ-
цией CreateMutex можно указать, чтобы он создавался сразу в занятом со-
стоянии:
#include <process.h>
#include <windows.h>
#define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL
unsigned __stdcall TProc( void *pdata )
{
WaitForSingleObject( hObject, 2000 );
WaitForSingleObject( hObject, 2000 );
Sleep( 1000 );
ReleaseMutex( (HANDLE)pdata );
ReleaseMutex( (HANDLE)pdata );
return 0;
}
Разработка параллельных приложений для ОС Windows
241
Семафоры
Семафор представляет собой счетчик, который считается свобод-
ным, если значение счетчика больше нуля, и занятым при нулевом значе-
нии. При создании семафора задаются его максимально допустимое и на-
чальное состояния. Ожидающие функции WaitFor... уменьшают значение
свободного семафора на 1, если счетчик ненулевой, или переходят в ре-
жим ожидания до тех пор пока кто-либо не увеличит значение семафора.
Увеличение счетчика осуществляется функцией ReleaseSemaphore:
#define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL
int main( void )
{
HANDLE hSem;
LONG lPrev;
hSem = CreateSemaphore( DEFAULT_SECURITY, 0, 5, NULL );
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_TIMEOUT */
ReleaseSemaphore( (HANDLE)dwData, 1, &lPrev );
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_OBJECT_0 */
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_TIMEOUT */
ReleaseSemaphore( (HANDLE)dwData, 2, &lPrev );
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_OBJECT_0 */
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_OBJECT_0 */
WaitForSingleObject( hSem, 100 );
/* код завершения WAIT_TIMEOUT */
CloseHandle( hSem );
return 0;
}
В примере создается семафор в первоначально занятом состоянии,
поэтому первое ожидание завершается по таймауту. После этого его счет-
чик увеличивается на 1, и следующее ожидание завершается успехом, при
этом счетчик семафора уменьшается и он снова становится занятым. В ре-
зультате третье ожидание завершается по таймауту. После этого счетчик
увеличивается на 2, и два последующих ожидания завершаются успехом,
после чего счетчик оказывается снова нулевым и третье ожидание завер-
шается по таймауту.
240
CIL и системное программирование в Microsoft .NET
240 CIL и системное программирование в Microsoft .NET Разработка параллельных приложений для ОС Windows 241 Семафоры К сожалению, средств для проверки текущего значения счетчика без Семафор представляет собой счетчик, который считается свобод- изменения состояния семафора нет: функция ReleaseSemaphore позволяет ным, если значение счетчика больше нуля, и занятым при нулевом значе- узнать предыдущее значение, но при этом обязательно увеличит его зна- нии. При создании семафора задаются его максимально допустимое и на- чение хотя бы на 1 (попытка увеличить на 0 или на отрицательную вели- чальное состояния. Ожидающие функции WaitFor... уменьшают значение чину рассматривается как ошибка), а ожидающая функция обязательно свободного семафора на 1, если счетчик ненулевой, или переходят в ре- уменьшит счетчик, если семафор был свободен. Поэтому для определения жим ожидания до тех пор пока кто-либо не увеличит значение семафора. значения счетчика надо использовать что-то вроде приведенного ниже Увеличение счетчика осуществляется функцией ReleaseSemaphore: примера: #define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL LONG lCounter; lCounter = 0; int main( void ) if ( WaitForSingleObject( hSem, 0 ) == WAIT_OBJECT_0 ) { ReleaseSemaphore( hSem, 1, &lCounter ); HANDLE hSem; /* теперь переменная lCounter содержит значение счетчика */ LONG lPrev; Семафоры предназначены для ограничения числа потоков, имею- hSem = CreateSemaphore( DEFAULT_SECURITY, 0, 5, NULL ); щих одновременный доступ к какому-либо ресурсу. WaitForSingleObject( hSem, 100 ); Мьютексы /* код завершения WAIT_TIMEOUT */ Объекты исключительного владения могут быть использованы в од- ReleaseSemaphore( (HANDLE)dwData, 1, &lPrev ); но время не более чем одним потоком. В этом отношении мьютексы по- WaitForSingleObject( hSem, 100 ); добны критическим секциям, с той оговоркой, что работа с ними выпол- /* код завершения WAIT_OBJECT_0 */ няется в режиме ядра (при использовании критических секций переход в WaitForSingleObject( hSem, 100 ); режим ядра необязателен) и что мьютексы могут быть использованы для /* код завершения WAIT_TIMEOUT */ межпроцессного взаимодействия, тогда как критические секции реализо- ReleaseSemaphore( (HANDLE)dwData, 2, &lPrev ); ваны для применения внутри процесса. WaitForSingleObject( hSem, 100 ); Для захвата мьютекса используется ожидающая функция WaitFor..., а /* код завершения WAIT_OBJECT_0 */ для освобождения – функция ReleaseMutex. При создании мьютекса функ- WaitForSingleObject( hSem, 100 ); цией CreateMutex можно указать, чтобы он создавался сразу в занятом со- /* код завершения WAIT_OBJECT_0 */ стоянии: WaitForSingleObject( hSem, 100 ); /* код завершения WAIT_TIMEOUT */ #includeCloseHandle( hSem ); #include return 0; #define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL } В примере создается семафор в первоначально занятом состоянии, unsigned __stdcall TProc( void *pdata ) поэтому первое ожидание завершается по таймауту. После этого его счет- { чик увеличивается на 1, и следующее ожидание завершается успехом, при WaitForSingleObject( hObject, 2000 ); этом счетчик семафора уменьшается и он снова становится занятым. В ре- WaitForSingleObject( hObject, 2000 ); зультате третье ожидание завершается по таймауту. После этого счетчик Sleep( 1000 ); увеличивается на 2, и два последующих ожидания завершаются успехом, ReleaseMutex( (HANDLE)pdata ); после чего счетчик оказывается снова нулевым и третье ожидание завер- ReleaseMutex( (HANDLE)pdata ); шается по таймауту. return 0; }
Страницы
- « первая
- ‹ предыдущая
- …
- 125
- 126
- 127
- 128
- 129
- …
- следующая ›
- последняя »