Windows Thread Synchronization 22






Using Semaphore Objects Program Example


The following example uses a semaphore object to limit the number of threads that can perform a particular task. First, it uses the CreateSemaphore() function to create the semaphore and to specify initial and maximum counts, then it uses the CreateThread() function to create the threads. Before a thread attempts to perform the task, it uses the WaitForSingleObject() function to determine whether the semaphore's current count permits it to do so. The wait function's time-out parameter is set to zero, so the function returns immediately if the semaphore is in the nonsignaled state. WaitForSingleObject() decrements the semaphore's count by one. When a thread completes the task, it uses the ReleaseSemaphore() function to increment the semaphore's count, thus enabling another waiting thread to perform the task.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.


Using Semaphore Objects Program Example: Creating new console application project of the Win32 C++


Then, add the source file and give it a suitable name.


Using Semaphore Objects Program Example: Adding new C++ source file to the existing project


Next, add the following source code.


#include <windows.h>

#include <stdio.h>


#define MAX_SEM_COUNT 10

#define THREADCOUNT 12


HANDLE ghSemaphore;




void wmain()



    DWORD ThreadID;

    int i;


    // Create a semaphore with initial and max counts of MAX_SEM_COUNT

    ghSemaphore = CreateSemaphore(

        NULL,           // default security attributes

        MAX_SEM_COUNT,  // initial count

        MAX_SEM_COUNT,  // maximum count

        NULL);          // unnamed semaphore


    if (ghSemaphore == NULL)


        wprintf(L"CreateSemaphore() error %d\n", GetLastError());




            wprintf(L"CreateSemaphore() is OK\n");


    // Create worker threads

    for( i=0; i < THREADCOUNT; i++ )


        aThread[i] = CreateThread(

                     NULL,       // default security attributes

                     0,          // default stack size

                     (LPTHREAD_START_ROUTINE) ThreadProc,

                     NULL,       // no thread function arguments

                     0,          // default creation flags

                     &ThreadID); // receive thread identifier


        if( aThread[i] == NULL )


            wprintf(L"CreateThread() error %d\n", GetLastError());




                  wprintf(L"Thread %d with ID %d was created...\n", i, ThreadID);



    // Wait for all threads to terminate

    wprintf(L"Waiting all the threads to terminate...\n");

    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);


    // Close thread and semaphore handles

    for( i=0; i < THREADCOUNT; i++ )


            if(CloseHandle(aThread[i]) != 0)

                  wprintf(L"Handle to thread %i was closed!\n", i);


                  wprintf(L"Failed to close the thread %i handle, error %d\n", i, GetLastError());



      if(CloseHandle(ghSemaphore) != 0)

            wprintf(L"Handle to Semaphore object was closed!\n", i);


            wprintf(L"Failed to close the Semaphore object handle, error %d\n", GetLastError());






    DWORD dwWaitResult;

    BOOL bContinue=TRUE;




        // Try to enter the semaphore gate

        dwWaitResult = WaitForSingleObject(

            ghSemaphore,   // handle to semaphore

            0L);           // zero-second time-out interval


        switch (dwWaitResult)


            // The semaphore object was signaled.

            case WAIT_OBJECT_0:

                // TODO: Perform task

                wprintf(L"Thread %d: wait succeeded...\n", GetCurrentThreadId());


                // Simulate thread spending time on task


                // Release the semaphore when task is finished

                if (!ReleaseSemaphore(

                        ghSemaphore,  // handle to semaphore

                        1,            // increase count by one

                        NULL) )       // not interested in previous count


                    wprintf(L"ReleaseSemaphore error %d\n", GetLastError());




            // The semaphore was nonsignaled, so a time-out occurred.

            case WAIT_TIMEOUT:

                wprintf(L"Thread %d: wait timed out...\n", GetCurrentThreadId());




    return TRUE;



Build and run the project. The following screenshots are the sample outputs.


Using Semaphore Objects Program Example: A sample of console program output


Using Semaphore Objects Program Example: Another sample console program output





< Thread Synchronization 21 | Thread Synchronization Programming | Win32 Programming | Thread Synchronization 23 >