Semaphore信号量

/************************************************************************
** Semaphore 信号量
** 可以将Mutex看作Semaphore的简化版,Mutex锁住的是一份资源,
** Semaphore锁住的是多份资源,可以让多个线程在“同一时间同时运行”
** 
** 主要函数:
** CreateSemaphore
** ReleaseSemaphore

** VS2008 MSND的例子
** ms-help://MS.MSDNQTR.v90.en/dllproc/base/createsemaphore.htm
************************************************************************/

#include <windows.h>
#include <stdio.h>

#define MAX_SEM_COUNT 5
#define THREADCOUNT 8

HANDLE ghSemaphore;

DWORD WINAPI ThreadProc( LPVOID );

void main()
{
    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            // 数目为1,就很像Mutex
        MAX_SEM_COUNT,  // maximum count
        NULL);          // unnamed semaphore

    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return;
    }

    // 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;
        }
    }

    // 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);
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{
    DWORD dwWaitResult; 
    BOOL bContinue=TRUE;

    while(bContinue)
    {
        // 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
            printf("***** Thread %d: wait succeeded ******\n", GetCurrentThreadId());
            bContinue=FALSE;            

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

            // Relase 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;
}

 

posted @ 2012-08-17 10:19  木愚  阅读(274)  评论(0编辑  收藏  举报