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