Platform SDK: DLLs, Processes, and Threads

Using Semaphore Objects

In the following example, a process uses a semaphore object to limit the number of windows it creates. First, it uses the CreateSemaphore function to create the semaphore and to specify initial and maximum counts.

HANDLE hSemaphore;
LONG cMax = 10;
LONG cPreviousCount;

// Create a semaphore with initial and max. counts of 10.

hSemaphore = CreateSemaphore( 
    NULL,   // no security attributes
    cMax,   // initial count
    cMax,   // maximum count
    NULL);  // unnamed semaphore

if (hSemaphore == NULL) 
{
    // Check for error.
}

Before any thread of the process creates a new window, it uses the WaitForSingleObject function to determine whether the semaphore's current count permits the creation of additional windows. The wait function's time-out parameter is set to zero, so the function returns immediately if the semaphore is nonsignaled.

DWORD dwWaitResult; 
 
// Try to enter the semaphore gate.

dwWaitResult = WaitForSingleObject( 
        hSemaphore,   // handle to semaphore
        0L);          // zero-second time-out interval

switch (dwWaitResult) { 

    // The semaphore object was signaled.
    case WAIT_OBJECT_0: 
        // OK to open another window.
        break; 

    // Semaphore was nonsignaled, so a time-out occurred.
    case WAIT_TIMEOUT: 
        // Cannot open another window.
        break; 
}

When a thread closes a window, it uses the ReleaseSemaphore function to increment the semaphore's count.

// Increment the count of the semaphore.

if (!ReleaseSemaphore( 
        hSemaphore,  // handle to semaphore
        1,           // increase count by one
        NULL) )      // not interested in previous count
{
    // Deal with the error.
}