Semaphore
A semaphore is a kernel object used to control access to a finite number of resources. It can be used for thread synchronization, limiting concurrency, and implementing producer‑consumer scenarios.
Key Functions
CreateSemaphore– Creates or opens a semaphore.OpenSemaphore– Opens an existing named semaphore.ReleaseSemaphore– Increments the semaphore count.WaitForSingleObject/WaitForMultipleObjects– Waits for the semaphore to become signaled.CloseHandle– Closes the semaphore handle.
Syntax Overview
// Create a semaphore
HANDLE hSem = CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
Parameters
| Parameter | Description |
|---|---|
| lpSecurityAttributes | Optional security descriptor. |
| lInitialCount | Initial count of the semaphore (>=0). |
| lMaximumCount | Maximum count (>=lInitialCount). |
| lpName | Optional name for a named semaphore. |
Example: Producer‑Consumer Using a Semaphore
#include <windows.h>
#include <stdio.h>
#define BUFFER_SIZE 5
HANDLE hEmptySlots;
HANDLE hFullSlots;
HANDLE hMutex;
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
DWORD WINAPI Producer(LPVOID param) {
for (int i = 0; i < 10; ++i) {
WaitForSingleObject(hEmptySlots, INFINITE);
WaitForSingleObject(hMutex, INFINITE);
buffer[in] = i;
printf("Produced: %d\n", i);
in = (in + 1) % BUFFER_SIZE;
ReleaseMutex(hMutex);
ReleaseSemaphore(hFullSlots, 1, NULL);
Sleep(100);
}
return 0;
}
DWORD WINAPI Consumer(LPVOID param) {
for (int i = 0; i < 10; ++i) {
WaitForSingleObject(hFullSlots, INFINITE);
WaitForSingleObject(hMutex, INFINITE);
int item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
ReleaseMutex(hMutex);
ReleaseSemaphore(hEmptySlots, 1, NULL);
Sleep(150);
}
return 0;
}
int main() {
hEmptySlots = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, NULL);
hFullSlots = CreateSemaphore(NULL, 0, BUFFER_SIZE, NULL);
hMutex = CreateMutex(NULL, FALSE, NULL);
HANDLE hThreads[2];
hThreads[0] = CreateThread(NULL, 0, Producer, NULL, 0, NULL);
hThreads[1] = CreateThread(NULL, 0, Consumer, NULL, 0, NULL);
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);
CloseHandle(hEmptySlots);
CloseHandle(hFullSlots);
CloseHandle(hMutex);
return 0;
}
This example demonstrates a classic producer‑consumer scenario where hEmptySlots and hFullSlots semaphores track buffer capacity, and a mutex protects shared data.
Comments