Windows thread API in the C program

Threads are created in the Windows API using the CreateThread() function. Just as in Pthreads, a set of attributes like security information, the size of the stack, and a flag for the thread is passed to this function. In the below program, we use the default values for these attributes. Once the summation thread is created, the parent must wait for it to complete before outputting the value of Sum, as the value is set by the summation thread.

Using the WaitForSingleObject() function, we perform the equivalent of pthread_join() in the Windows API, which causes the creating thread to block until the summation thread has exited. In situations that require waiting for multiple threads to complete, the WaitForMultipleObjects() function is used.

Syntax

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
);

DWORD WaitForSingleObject(
    HANDLE hHandle,
    DWORD dwMilliseconds
);

WaitForMultipleObjects Parameters

The WaitForMultipleObjects() function is passed four parameters −

  • The number of objects to wait for
  • A pointer to the array of objects
  • A flag indicating whether all objects have been signaled
  • A timeout duration (or INFINITE)

For example, if THandles is an array of thread HANDLE objects of size N, the parent thread can wait for all its child threads to complete with this statement −

WaitForMultipleObjects(N, THandles, TRUE, INFINITE);

Example: Multithreaded C Program Using Windows API

Note: This example requires a Windows environment with Visual Studio or MinGW compiler that supports Windows API headers.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

DWORD Sum; /* data is shared by the thread(s) */

/* thread runs in this separate function */
DWORD WINAPI Summation(LPVOID Param) {
    DWORD Upper = *(DWORD*)Param;
    for (DWORD i = 0; i <= Upper; i++)
        Sum += i;
    return 0;
}

int main(int argc, char *argv[]) {
    DWORD ThreadId;
    HANDLE ThreadHandle;
    int Param;
    
    if (argc != 2) {
        fprintf(stderr, "An integer parameter is required<br>");
        return -1;
    }
    
    Param = atoi(argv[1]);
    if (Param < 0) {
        fprintf(stderr, "An integer >= 0 is required<br>");
        return -1;
    }
    
    /* create the thread */
    ThreadHandle = CreateThread(
        NULL,        /* default security attributes */
        0,           /* default stack size */
        Summation,   /* thread function */
        &Param,      /* parameter to thread function */
        0,           /* default creation flags */
        &ThreadId    /* returns the thread identifier */
    );
    
    if (ThreadHandle != NULL) {
        /* now wait for the thread to finish */
        WaitForSingleObject(ThreadHandle, INFINITE);
        
        /* close the thread handle */
        CloseHandle(ThreadHandle);
        
        printf("sum = %d<br>", Sum);
    }
    
    return 0;
}

Key Points

  • CreateThread() creates a new thread with specified attributes and function
  • WaitForSingleObject() blocks the calling thread until the specified thread completes
  • CloseHandle() must be called to release thread resources
  • Global variables like Sum are shared between threads

Conclusion

Windows API provides powerful threading capabilities through CreateThread() and synchronization functions. Proper thread management requires waiting for completion and releasing handles to prevent resource leaks.

Updated on: 2026-03-15T12:13:38+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements