Listing 5 The threads call the Execute() function on the Commands that they receive
#include <iostream> #include <vector> #include <windows.h> HANDLE condition; HANDLE mutex; class Command; std::vector < Command* > queue; // base command class class Command { public: Command () {} ~Command () {} // the actual command logic resides in Execute () virtual void Execute () = 0; }; class Command_A : public Command { public: Command_A () {} ~Command_A () {} void Execute () { std::cout << "Doing some work" << std::endl; } }; class Command_B : public Command { public: Command_B () {} ~Command_B () {} void Execute () { std::cout << "Doing some other work" << std::endl; } }; void thread_entry () { for ( ;; ) { WaitForSingleObject ( mutex, INFINITE ); if ( queue.empty () ) { ReleaseMutex ( mutex ); std::cout << "thread going to sleep" << std::endl; WaitForSingleObject ( condition, INFINITE ); WaitForSingleObject ( mutex, INFINITE ); std::cout << "thread awake" << std::endl; } if ( queue.empty () ) { std::cout << "work queue is empty" << std::endl; ReleaseMutex ( mutex ); continue; } Command* command = queue.back (); queue.pop_back (); ReleaseMutex ( mutex ); command->Execute (); delete command; Sleep ( 1 ); } } int main () { HANDLE threads[ 10 ]; mutex = CreateMutex ( NULL, FALSE, NULL ); condition = CreateEvent ( NULL, FALSE, FALSE, NULL ); for ( int i = 10; i > 0; --i ) { threads[ i - 1 ] = CreateThread ( NULL, 0, ( LPTHREAD_START_ROUTINE ) thread_entry, NULL, 0, NULL ); } for ( int index = 10; index > 0; --index ) { WaitForSingleObject ( mutex, INFINITE ); Command* command = index % 2 ? ( Command* ) new Command_A : ( Command* ) new Command_B; queue.push_back ( command ); SetEvent ( condition ); ReleaseMutex ( mutex ); } WaitForSingleObject ( threads[ 0 ], INFINITE ); return ( 0 ); }