Creating Consumer and Producer Objects

   

Now that you understand how the thread will be synchronized by encapsulating the synchronization logic within the data object, you will add the code necessary for the producer and consumer objects. As you'll recall, the delegates within each of these classes will be doing all the work. Before you implement the delegates, you need to create another constructor for each of the classes. Because this lesson is meant to show synchronization, each class will work with the same data object. This single IntDataBlock object will be created within the _tmain function and passed to the consumer and producer objects through each of their overloaded constructors. Create an overloaded constructor for each of the classes that accepts a pointer to an IntDataBlock object and assigns a private member variable to the constructor parameter. Also, change the _tmain function by creating an IntDataBlock instance and passing them to the producer and consumer classes rather than using the default constructors for each class. You can use Listing 19.3 to help you.

graphics/bulb.gif

Delegates are used extensively throughout the .NET Framework. In order for a delegate to have access to data that it can use, you can follow the example this hour that places the delegate function within an actual object. By doing this, you gain the added benefit of object-oriented programming with delegates, which otherwise isn't possible by using a single global function instead.

Listing 19.3 Implementing the Overloaded Constructors and Delegates for the Producer and Consumer Classes
 1: public __gc class Consumer  2: {  3: public:  4:     Consumer(){}  5:  6:     IntDataBlock* m_pDataBlock;  7:  8:     Consumer( IntDataBlock* pDataBlock )  9:     { 10:         m_pDataBlock = pDataBlock; 11:     } 12: 13:     void ThreadRun( ) 14:     { 15:         for(int i=1; i<=5; i++) 16:         { 17:             m_pDataBlock->WriteData( i ); 18:         } 19:     } 20: }; 21: 22: public __gc class Producer 23: { 24: public: 25: 26:     IntDataBlock* m_pDataBlock; 27: 28:     Producer( IntDataBlock* pDataBlock ) 29:     { 30:         m_pDataBlock = pDataBlock; 31:     } 32: 33:     void ThreadRun() 34:     { 35:         int nData; 36:         for(int i=1; i<=5; i++) 37:         { 38:             nData = m_pDataBlock->ReadData( ); 39:         } 40:     } 41: }; 42: 43: // This is the entry point for this application 44: int _tmain(void) 45: { 46:     int nResult = 0; 47:     IntDataBlock* pData = new IntDataBlock( ); 48: 49:     Producer* pProducer = new Producer( pData ); 50: 51:     Consumer* pConsumer = new Consumer( pData ); 52: 53:     Thread* pProdThread = new Thread 54:         (new ThreadStart(pProducer, &Producer::ThreadRun )); 55:     Thread* pconsThread = new Thread 56:         (new ThreadStart(pConsumer, &Consumer::ThreadRun )); 57: 58:     try 59:     { 60:         pconsThread->Start( ); 61:         pProdThread->Start( ); 62: 63:         pProdThread->Join( ); 64:         pconsThread->Join( ); 65:     } 66:     catch (ThreadStateException* e) 67:     { 68:         Console::WriteLine(e->Message); 69:         nResult = 1; 70:     } 71:     catch (ThreadInterruptedException* e) 72:     { 73:         Console::WriteLine(e->Message); 74:         nResult = 1; 75:     } 76: 77:     Environment::ExitCode = nResult; 78: } 

The code to actually produce and consume data is quite simple because all the data logic is contained within the data object. To produce data, simply create a for loop with a set number of iterations and for each iteration, call the WriteData function passing the loop index as the parameter. For the consumer object, simply create another loop and call the ReadData function on the IntDataBlock variable.

You can now compile your application. It may be a good idea to place Console::WriteLine calls throughout various places in your code. This will help you to see how the synchronization works and what the sequence of events is as data is produced and consumed. Your output should appear similar to Figure 19.4.

Figure 19.4. Output of a multiple-threaded producer/consumer application with synchronization.

graphics/19fig04.jpg


   
Top


Sams Teach Yourself Visual C++. NET in 24 Hours
Sams Teach Yourself Visual C++.NET in 24 Hours
ISBN: 0672323230
EAN: 2147483647
Year: 2002
Pages: 237

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net