CreateSemaphore, ReleaseSemaphore

Создается семафор функцией 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

Как видите третий поток ждет. И как только освободился семафор он может дальше что-то делать.

 
« Предыдущая статья   Следующая статья »