Using Synchronization in Windows (sample 5 to 8)

来源:互联网 发布:公司网站域名申请 编辑:程序博客网 时间:2024/06/03 14:08

Using Ssynchronization in windows (sample 1 to 4)


5.) Using Condition Variables

#include <windows.h>#include <stdlib.h>#include <stdio.h>#define BUFFER_SIZE 10#define PRODUCER_SLEEP_TIME_MS 500#define CONSUMER_SLEEP_TIME_MS 2000LONG Buffer[BUFFER_SIZE];LONG LastItemProduced;ULONG QueueSize;ULONG QueueStartOffset;ULONG TotalItemsProduced;ULONG TotalItemsConsumed;CONDITION_VARIABLE BufferNotEmpty;CONDITION_VARIABLE BufferNotFull;CRITICAL_SECTION   BufferLock;BOOL StopRequested;DWORD WINAPI ProducerThreadProc (PVOID p){    ULONG ProducerId = (ULONG)(ULONG_PTR)p;    while (true)    {        // Produce a new item.        Sleep (rand() % PRODUCER_SLEEP_TIME_MS);        ULONG Item = InterlockedIncrement (&LastItemProduced);        EnterCriticalSection (&BufferLock);        while (QueueSize == BUFFER_SIZE && StopRequested == FALSE)        {            // Buffer is full - sleep so consumers can get items.            SleepConditionVariableCS (&BufferNotFull, &BufferLock, INFINITE);        }        if (StopRequested == TRUE)        {            LeaveCriticalSection (&BufferLock);            break;        }        // Insert the item at the end of the queue and increment size.        Buffer[(QueueStartOffset + QueueSize) % BUFFER_SIZE] = Item;        QueueSize++;        TotalItemsProduced++;        printf ("Producer %u: item %2d, queue size %2u\r\n", ProducerId, Item, QueueSize);        LeaveCriticalSection (&BufferLock);        // If a consumer is waiting, wake it.        WakeConditionVariable (&BufferNotEmpty);    }    printf ("Producer %u exiting\r\n", ProducerId);    return 0;}DWORD WINAPI ConsumerThreadProc (PVOID p){    ULONG ConsumerId = (ULONG)(ULONG_PTR)p;    while (true)    {        EnterCriticalSection (&BufferLock);        while (QueueSize == 0 && StopRequested == FALSE)        {            // Buffer is empty - sleep so producers can create items.            SleepConditionVariableCS (&BufferNotEmpty, &BufferLock, INFINITE);        }        if (StopRequested == TRUE && QueueSize == 0)        {            LeaveCriticalSection (&BufferLock);            break;        }        // Consume the first available item.        LONG Item = Buffer[QueueStartOffset];        QueueSize--;        QueueStartOffset++;        TotalItemsConsumed++;        if (QueueStartOffset == BUFFER_SIZE)        {            QueueStartOffset = 0;        }        printf ("Consumer %u: item %2d, queue size %2u\r\n",             ConsumerId, Item, QueueSize);        LeaveCriticalSection (&BufferLock);        // If a producer is waiting, wake it.        WakeConditionVariable (&BufferNotFull);        // Simulate processing of the item.        Sleep (rand() % CONSUMER_SLEEP_TIME_MS);    }    printf ("Consumer %u exiting\r\n", ConsumerId);    return 0;}void __cdecl wmain (int argc, const wchar_t* argv[]){    InitializeConditionVariable (&BufferNotEmpty);    InitializeConditionVariable (&BufferNotFull);    InitializeCriticalSection (&BufferLock);    DWORD id;    HANDLE hProducer1 = CreateThread (NULL, 0, ProducerThreadProc, (PVOID)1, 0, &id);    HANDLE hConsumer1 = CreateThread (NULL, 0, ConsumerThreadProc, (PVOID)1, 0, &id);    HANDLE hConsumer2 = CreateThread (NULL, 0, ConsumerThreadProc, (PVOID)2, 0, &id);    puts ("Press enter to stop...");    getchar();    EnterCriticalSection (&BufferLock);    StopRequested = TRUE;    LeaveCriticalSection (&BufferLock);    WakeAllConditionVariable (&BufferNotFull);    WakeAllConditionVariable (&BufferNotEmpty);    WaitForSingleObject (hProducer1, INFINITE);    WaitForSingleObject (hConsumer1, INFINITE);    WaitForSingleObject (hConsumer2, INFINITE);    printf ("TotalItemsProduced: %u, TotalItemsConsumed: %u\r\n",         TotalItemsProduced, TotalItemsConsumed);}


6.) Using Waitable Timer Objects

#define _WIN32_WINNT 0x0500#include <windows.h>#include <stdio.h>int main(){    HANDLE hTimer = NULL;    LARGE_INTEGER liDueTime;    liDueTime.QuadPart = -100000000LL;    // Create an unnamed waitable timer.    hTimer = CreateWaitableTimer(NULL, TRUE, NULL);    if (NULL == hTimer)    {        printf("CreateWaitableTimer failed (%d)\n", GetLastError());        return 1;    }    printf("Waiting for 10 seconds...\n");    // Set a timer to wait for 10 seconds.    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))    {        printf("SetWaitableTimer failed (%d)\n", GetLastError());        return 2;    }    // Wait for the timer.    if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)        printf("WaitForSingleObject failed (%d)\n", GetLastError());    else printf("Timer was signaled.\n");    return 0;}

7.) Using Singly Linked Lists

#include <windows.h>#include <malloc.h>#include <stdio.h>// Structure to be used for a list item; the first member is the // SLIST_ENTRY structure, and additional members are used for data.// Here, the data is simply a signature for testing purposes. typedef struct _PROGRAM_ITEM {    SLIST_ENTRY ItemEntry;    ULONG Signature; } PROGRAM_ITEM, *PPROGRAM_ITEM;int main( ){    ULONG Count;    PSLIST_ENTRY pFirstEntry, pListEntry;    PSLIST_HEADER pListHead;    PPROGRAM_ITEM pProgramItem;    // Initialize the list header.    pListHead = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER),       MEMORY_ALLOCATION_ALIGNMENT);    if( NULL == pListHead )    {        printf("Memory allocation failed.\n");        return -1;    }    InitializeSListHead(pListHead);    // Insert 10 items into the list.    for( Count = 1; Count <= 10; Count += 1 )    {        pProgramItem = (PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM),            MEMORY_ALLOCATION_ALIGNMENT);        if( NULL == pProgramItem )        {            printf("Memory allocation failed.\n");            return -1;        }        pProgramItem->Signature = Count;        pFirstEntry = InterlockedPushEntrySList(pListHead,                        &(pProgramItem->ItemEntry));     }    // Remove 10 items from the list and display the signature.    for( Count = 10; Count >= 1; Count -= 1 )    {        pListEntry = InterlockedPopEntrySList(pListHead);        if( NULL == pListEntry )        {            printf("List is empty.\n");            return -1;        }          pProgramItem = (PPROGRAM_ITEM)pListEntry;        printf("Signature is %d\n", pProgramItem->Signature);    // This example assumes that the SLIST_ENTRY structure is the     // first member of the structure. If your structure does not     // follow this convention, you must compute the starting address     // of the structure before calling the free function.        _aligned_free(pListEntry);    }    // Flush the list and verify that the items are gone.    pListEntry = InterlockedFlushSList(pListHead);    pFirstEntry = InterlockedPopEntrySList(pListHead);    if (pFirstEntry != NULL)    {        printf("Error: List is not empty.\n");        return -1;    }    _aligned_free(pListHead);    return 1;}

8.) Using Timer Queues


#define _WIN32_WINNT 0x0500#include <windows.h>#include <stdio.h>HANDLE gDoneEvent;VOID CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired){    if (lpParam == NULL)    {        printf("TimerRoutine lpParam is NULL\n");    }    else    {        // lpParam points to the argument; in this case it is an int        printf("Timer routine called. Parameter is %d.\n",                 *(int*)lpParam);    }    SetEvent(gDoneEvent);}int main(){    HANDLE hTimer = NULL;    HANDLE hTimerQueue = NULL;    int arg = 123;    // Use an event object to track the TimerRoutine execution    gDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    if (NULL == gDoneEvent)    {        printf("CreateEvent failed (%d)\n", GetLastError());        return 1;    }    // Create the timer queue.    hTimerQueue = CreateTimerQueue();    if (NULL == hTimerQueue)    {        printf("CreateTimerQueue failed (%d)\n", GetLastError());        return 2;    }    // Set a timer to call the timer routine in 10 seconds.    if (!CreateTimerQueueTimer( &hTimer, hTimerQueue,             (WAITORTIMERCALLBACK)TimerRoutine, &arg , 10000, 0, 0))    {        printf("CreateTimerQueueTimer failed (%d)\n", GetLastError());        return 3;    }    // TODO: Do other useful work here     printf("Call timer routine in 10 seconds...\n");    // Wait for the timer-queue thread to complete using an event     // object. The thread will signal the event at that time.    if (WaitForSingleObject(gDoneEvent, INFINITE) != WAIT_OBJECT_0)        printf("WaitForSingleObject failed (%d)\n", GetLastError());    CloseHandle(gDoneEvent);    // Delete all timers in the timer queue.    if (!DeleteTimerQueue(hTimerQueue))        printf("DeleteTimerQueue failed (%d)\n", GetLastError());    return 0;}


原创粉丝点击