Шаг 117 - CreateSemaphore, ReleaseSemaphore.
Очень полезно сначало прочитать MSDN: "Шаг 81 - Что такое семафоры (Semaphore)". Создается семафор функцией CreateSemaphore():
HANDLE CreateSemaphore
(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // атрибут доступа
LONG lInitialCount, // инициализированное начальное состояние счетчика
LONG lMaximumCount, // максимальное количество обращений
LPCTSTR lpName // имя объекта
);
При успешном выполнении функция вернет идентификатор семафора, в противном случае NULL. После того как необходимость в работе с объектом отпала нужно вызвать функцию ReleaseSemaphore(), чтобы освободить счетчик.
BOOL ReleaseSemaphore
(
HANDLE hSemaphore, // хенд семафора
LONG lReleaseCount, // на сколько изменять счетчик
LPLONG lpPreviousCount // предыдущее значение
);
При успешном выполнении возвращаемое значение ненулевое. Для уничтожения семафора нужно вызвать CloseHandle(). Давайте рассмотрим пример. Вот он:
// TestSemaphore.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"
HANDLE hSemaphore;
LONG cMax = 2;
void Test1(void *);
void Test2(void *);
void Test3(void *);
void main()
{
hSemaphore = CreateSemaphore(
NULL, // нет атрибута
cMax, // начальное состояние
cMax, // максимальное состояние
NULL); // без имени
if (!hSemaphore == NULL)
{
if (_beginthread(Test1,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test2,1024,NULL)==-1)
cout << "Error begin thread " << endl;
if (_beginthread(Test3,1024,NULL)==-1)
cout << "Error begin thread " << endl;
Sleep(10000);
CloseHandle(hSemaphore);
}
else cout << "error create semaphore" << endl;
}
void Test1(void *)
{
cout << "Test1 Running" << endl;
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject(
hSemaphore, // указатель на семафор
1); // интерфал ожидания
cout << "Test 1 TIMEOUT" << endl;
}
Sleep(1000);
if (ReleaseSemaphore(
hSemaphore, // указатель на светофор
1, // изменяет счетчик на 1
NULL)) cout << " ReleaseSemaphore Ok Test1" << endl;
_endthread();
}
void Test2(void *)
{
cout << "Test2 Running" << endl;
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject(hSemaphore,1);
cout << "Test 2 TIMEOUT" << endl;
}
Sleep(1000);
if (ReleaseSemaphore(hSemaphore,1,NULL))
cout << " ReleaseSemaphore Ok Test2" << endl;
_endthread();
}
void Test3(void *)
{
cout << "Test2 Running" << endl;
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject(hSemaphore,1);
cout << "Test 3 TIMEOUT" << endl;
}
if (ReleaseSemaphore(hSemaphore,1,NULL))
cout << " ReleaseSemaphore Ok Test3" << endl;
_endthread();
}
В данном примере создается семафор. Запускаются три потока, каждый из которых обрашается к семафору. Вот только разрешается обращаться всего двум потокам. Поэтому Test3 будет ждать, пока кто-то освободит семафор. Вот результат:
.......
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
ReleaseSemaphore Ok Test1
Test 3 TIMEOUT
ReleaseSemaphore Ok Test2
ReleaseSemaphore Ok Test3
Press any key to continue
Как видите третий поток ждет. И как только освободился семафор он может дальше что-то делать.
Предыдущий Шаг | Следующий Шаг | Оглавление
By Artem.
Используются технологии uCoz
|