//*************************************************************** // From the book "Win32 System Services: The Heart of Windows 98 // and Windows 2000" // by Marshall Brain // Published by Prentice Hall // // Copyright 1995, by Prentice Hall. // // This code demonstrates a solution to the bounded buffer // problem using semaphores. //*************************************************************** // buffer.cpp #include #include typedef struct _NODE { int data; _NODE *next; } NODE; NODE *top = 0; HANDLE empty, full; CRITICAL_SECTION critSec; CRITICAL_SECTION coutCritSec; const MAX_BUFFERS = 5; void push(int value) { NODE *temp; EnterCriticalSection(&critSec); temp = new NODE; temp->data = value; temp->next = top; top = temp; LeaveCriticalSection(&critSec); } int pop() { NODE *temp; int value; EnterCriticalSection(&critSec); if (top == 0) { LeaveCriticalSection(&critSec); return 0; } temp = top; value = top->data; top = top->next; delete temp; LeaveCriticalSection(&critSec); return value; } VOID ReadThread(VOID) { int x, p; LONG count; for (x=0; x<10; x++) { WaitForSingleObject(full, INFINITE); p = pop(); ReleaseSemaphore(empty, 1, &count); EnterCriticalSection(&coutCritSec); cout << "Read iteration: " << x << " value popped: " << p << " empty count: " << count << endl; LeaveCriticalSection(&coutCritSec); Sleep(200); } } VOID WriteThread(VOID) { int x; LONG count; for (x=0; x<10; x++) { WaitForSingleObject(empty, INFINITE); push(x); ReleaseSemaphore(full, 1, &count); EnterCriticalSection(&coutCritSec); cout << "Write iteration: " << x << " full count: " << count << endl; LeaveCriticalSection(&coutCritSec); Sleep(100); } } const INT numThreads=2; void main(void) { HANDLE handles[numThreads]; DWORD threadID; // Init synchronization InitializeCriticalSection(&critSec); InitializeCriticalSection(&coutCritSec); full = CreateSemaphore(0, 0, MAX_BUFFERS, 0); empty = CreateSemaphore(0, MAX_BUFFERS, MAX_BUFFERS, 0); // create a thread to read from the buffer handles[0]=CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ReadThread, 0, 0, &threadID); // create a thread to write to the buffer handles[1]=CreateThread(0, 0, (LPTHREAD_START_ROUTINE) WriteThread, 0, 0, &threadID); // wait for all threads to finish execution WaitForMultipleObjects(numThreads, handles, TRUE, INFINITE); // Clean up CloseHandle(empty); CloseHandle(full); DeleteCriticalSection(&critSec); DeleteCriticalSection(&coutCritSec); }