Создается семафор функцией 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
Как видите третий поток ждет. И как только освободился семафор он может дальше что-то делать. |