Составители:
Рубрика:
К сожалению, средств для проверки текущего значения счетчика без
изменения состояния семафора нет: функция 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 */ #include
CloseHandle( 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
- …
- следующая ›
- последняя »
