线程同步之Semaphore

线程同步之信号量

Semaphore

信号量。

它维护一个计数,当值大于0时,信号量对象处于已传信状态。通常用数值表示可用资源的个数。

WaitForSingleObject()令信号量减一;ReleaseSemaphore()令信号量加一。

//Semaphore
//this example is from msdn
#include 
#include 

#define MAX_SEM_COUNT 6
#define THREADCOUNT 8

HANDLE ghSemaphore;

DWORD WINAPI ThreadProc( LPVOID );

int main( void )
{
    HANDLE aThread[THREADCOUNT];
    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) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }

    // 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 ){
            printf("CreateThread error: %d\n", GetLastError());
            return 1;
        }
    }

    // Wait for all threads to terminate
    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

    // Close thread and semaphore handles
    for( i=0; i < THREADCOUNT; i++ )
        CloseHandle(aThread[i]);
    CloseHandle(ghSemaphore);
    return 0;
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{
    // lpParam not used in this example
    UNREFERENCED_PARAMETER(lpParam);

    DWORD dwWaitResult; 
    BOOL bContinue=TRUE;

    while(bContinue)
    {
        // Try to enter the semaphore gate.
        dwWaitResult = WaitForSingleObject( 
            ghSemaphore,   // handle to semaphore
            1L);           // zero-second time-out interval
        switch (dwWaitResult) 
        { 
            // The semaphore object was signaled.
            case WAIT_OBJECT_0: 
                // TODO: Perform task
                printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
                bContinue=FALSE;            

                // Simulate thread spending time on task
                Sleep(5);

                // Release the semaphore when task is finished
                if (!ReleaseSemaphore( 
                        ghSemaphore,  // handle to semaphore
                        1,            // increase count by one
                        NULL) )       // not interested in previous count
                {
                    printf("ReleaseSemaphore error: %d\n", GetLastError());
                }
                break; 

            // The semaphore was nonsignaled, so a time-out occurred.
            case WAIT_TIMEOUT: 
                printf("Thread %d: wait timed out\n", GetCurrentThreadId());
                break; 
        }
    }
    return TRUE;
}
/*
Thread 7752: wait succeeded
Thread 9520: wait succeeded
Thread 10852: wait succeeded
Thread 5352: wait succeeded
Thread 8164: wait succeeded
Thread 10060: wait succeeded
Thread 4800: wait timed out
Thread 4516: wait timed out
Thread 4516: wait timed out
Thread 4800: wait timed out
Thread 4800: wait timed out
Thread 4800: wait succeeded
Thread 4516: wait timed out
Thread 4516: wait succeeded
请按任意键继续. . .
*/

分析:

信号量值为6,MAX_SEM_COUNT ,而用到信号量的线程有8,THREADCOUNT,不包括main函数线程。所以前6个创建好的线程WaitForSingleObject()返回值为WAIT_OBJECT_0,不会阻塞。而接下来的线程WaitForSingleObject()返回值为 WAIT_TIMEOUT,它们等其他P操作成功的线程 Sleep(5)后做V操作,才能获得WAIT_OBJECT_0返回值。
8个ThreadProc线程执行完毕,主函数中WaitForMultipleObjects()函数才返回。

你可能感兴趣的:(Windows)