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.
}