$search
00001 // 00002 // main.cpp: implements and tests CThread and CTask classes 00003 // 00004 // Copyright (C) Walter E. Capers. All rights reserved 00005 // 00006 // This source is free to use as you like. If you make 00007 // any changes, keep me in the loop. Email your changes 00008 // to walt.capers@comcast.net. 00009 // 00010 // 00011 00012 #include <blort/ThreadObject/Thread.h> 00013 #include <iostream> 00014 using namespace std; 00015 00016 /* 00017 * CIncrementThread 00018 * Class derived from CThread which redefines OnTask 00019 * 00020 */ 00021 class CIncrementThread : public CThread 00022 { 00023 public: 00024 int counter; 00025 00026 virtual BOOL OnTask( LPVOID lpv ) 00027 { 00028 ThreadId_t id; 00029 00030 GetId(&id); 00031 if( lpv ) 00032 { 00033 int *pInt = (int *)lpv; 00034 00035 //dont' use cout here, output could be broken up due to threading 00036 printf("\tthread(%ld, counter+%d=%d, counter incremented\n",id,*pInt,(counter+=*pInt)); 00037 } 00038 return TRUE; 00039 } 00040 00041 virtual BOOL OnTask() 00042 { 00043 ThreadId_t id; 00044 00045 GetId(&id); 00046 //don't use cout here, output could be broken up due to threading 00047 m_mutex.Lock(); // protect the counter variable 00048 printf("\tthread(%ld, counter++= %d, counter incremented)\n",id,(++counter)); 00049 m_mutex.Unlock(); 00050 00051 00052 return TRUE; 00053 } 00054 00055 int GetValue() 00056 { 00057 int counterValue; 00058 m_mutex.Lock(); // protect the counter variable 00059 counterValue = counter; 00060 m_mutex.Unlock(); 00061 return counter; 00062 } 00063 00064 void Reset() 00065 { 00066 m_mutex.Lock(); 00067 counter = 0; 00068 m_mutex.Unlock(); 00069 } 00070 00071 CIncrementThread(){counter=0;} 00072 ~CIncrementThread(){} 00073 }; 00074 00075 class CTaskIncrementer: public CTask 00076 { 00077 private: 00078 int counter; 00079 int incr; 00080 public: 00081 void SetIncr(int iValue) 00082 { 00083 m_mutex.Lock(); 00084 incr = iValue; 00085 m_mutex.Unlock(); 00086 } 00087 00088 int GetIncrementValue() 00089 { 00090 int incrValue; 00091 m_mutex.Lock(); 00092 incrValue=incr; 00093 m_mutex.Unlock(); 00094 return incrValue; 00095 } 00096 00097 int GetValue() 00098 { 00099 int counterValue; 00100 m_mutex.Lock(); // protect the counter variable 00101 counterValue = counter; 00102 m_mutex.Unlock(); 00103 return counter; 00104 } 00105 00106 BOOL Task() 00107 { 00108 ThreadId_t id; 00109 00110 Thread(&id); 00111 00112 m_mutex.Lock(); 00113 printf("\tthread(%ld, counter+%d=%d, counter incremented\n",id,incr,(counter+=incr)); 00114 m_mutex.Unlock(); 00115 return TRUE; 00116 } 00117 CTaskIncrementer(){counter=0;incr=0;} 00118 ~CTaskIncrementer(){} 00119 }; 00120 00121 00122 00123 /* 00124 * 00125 * MyTaskClass 00126 * class derived from CTask which redefines Task 00127 * Task is called by CThreads OnTask member function. 00128 * 00129 */ 00130 class MyTaskClass: public CTask 00131 { 00132 public: 00133 BOOL Task() 00134 { 00135 cout << "\tperformed a ctask task\n"; 00136 return TRUE; 00137 } 00138 MyTaskClass(){} 00139 ~MyTaskClass(){} 00140 }; 00141 00142 int 00143 main(int argc, 00144 char *argv[] ) 00145 { 00146 int increment=10; 00147 00148 CIncrementThread *pThreadInc; 00149 00150 cout << "\n****** T H R E A D T E S T *********\n\n"; 00151 00152 cout << "--INSTANTIATING CINCREMENTTHREAD DERIVED FROM CTHREAD\n"; 00153 pThreadInc = new CIncrementThread; 00154 00155 if( pThreadInc ) 00156 { 00157 if( pThreadInc->PingThread(500) ) 00158 { 00159 cout << "\nSENDING EVENT + 10\n"; 00160 pThreadInc->Event((LPVOID)&increment); 00161 Sleep(500); 00162 cout << "\nSENDING EVENT ++\n"; 00163 pThreadInc->Event(); 00164 Sleep(500); 00165 } 00166 else { 00167 cout << "\nTHREAD DID NOT START\n"; 00168 exit(0); 00169 } 00170 cout << "\n--CHANGING THREAD MODEL TO INTERVAL BASED\n"; 00171 pThreadInc->SetThreadType(ThreadTypeIntervalDriven,100); 00172 Sleep(500); 00173 cout << "\n--CHANGING THREAD MODEL BACK TO EVENT DRIVEN\n"; 00174 pThreadInc->SetThreadType(ThreadTypeEventDriven); 00175 Sleep(500); 00176 cout << "\n--SENDING + 10\n"; 00177 pThreadInc->Event((LPVOID)&increment); 00178 Sleep(500); 00179 cout << "\n--DESTROYING OBJECT\n"; 00180 delete pThreadInc; 00181 Sleep(500); 00182 } 00183 else 00184 { 00185 cout << "FAILED TO ALLOCATE THREAD\n"; 00186 exit(0); 00187 } 00188 00189 cout << "\n--INSTANTIATING AN ARRAY OF TEN CINCREMENTTHREADS DERIVED FROM CTHREAD\n"; 00190 pThreadInc = new CIncrementThread [10]; 00191 if( pThreadInc ) 00192 { 00193 if( pThreadInc[9].PingThread(2000) ) 00194 { 00195 for(int i=0; i<10 ; i++ ) 00196 { 00197 pThreadInc[i].Event(); 00198 } 00199 Sleep(500); 00200 cout << "\n\n--DESTROYING OBJECT ARRAY\n"; 00201 delete [] pThreadInc; 00202 } 00203 else { 00204 cout << "\nTHREADS DID NOT START\n"; 00205 exit(0); 00206 } 00207 } 00208 else { 00209 cout << "FAILED TO ALLOCATE THREADS\n"; 00210 exit(0); 00211 } 00212 00213 cout << "\n--INSTANTIATING A CINCRMENTTHREAD BY DECLARATION\n"; 00214 { 00215 CIncrementThread th; 00216 00217 if( th.PingThread(2000) ) 00218 { 00219 cout << "\nSENDING EVENT\n"; 00220 th.Event(); 00221 Sleep(500); 00222 } 00223 else 00224 { 00225 cout << "FAILED TO START THREAD\n"; 00226 exit(0); 00227 } 00228 cout << "\nLEAVING SCOPE\n"; 00229 00230 } 00231 00232 cout << "\n--INSTANTIATING A CINCREMENTTHREAD BY DECLARATION\n"; 00233 { 00234 CIncrementThread MyThread; // object allocated and thread started 00235 int two = 2; 00236 while( MyThread.GetValue() < 20 ) 00237 { 00238 MyThread.Event(); // increment value by one 00239 Sleep(100); // pauses the root thread for 100 milli-seconds 00240 } 00241 00242 MyThread.Reset(); 00243 while( MyThread.GetValue() < 40 ) 00244 { 00245 MyThread.Event(&two); 00246 Sleep(100); 00247 } 00248 00249 } 00250 00251 cout << "--INSTANTIATING THE ORIGIONAL CTHREAD CLASS BY DECLARATION\n"; 00252 { 00253 MyTaskClass myTask; 00254 CThread thread; 00255 thread.Event(&myTask); 00256 while( myTask.Status() != TaskStatusCompleted ) 00257 Sleep(500); 00258 00259 thread.Event(&myTask); 00260 myTask.Wait(1); 00261 } 00262 00263 cout << "\n--INSTANTIATING THE ORIGIONAL CTHREAD CLASS BY DECLARATION\n"; 00264 { 00265 MyTaskClass *pMyTask = new MyTaskClass; 00266 00267 CThread thread; 00268 thread.Event(pMyTask); 00269 if( pMyTask->Wait(1) ) 00270 { 00271 cout << "\tfreeing pMyTask\n"; 00272 delete pMyTask; 00273 } 00274 } 00275 00276 cout << "\n--INSTANTIATING a CTHREAD AND USING A CTASK OBJECT\n"; 00277 { 00278 CTaskIncrementer incr; 00279 CThread thr; 00280 00281 incr.SetIncr(2); 00282 while( incr.GetValue() < 40 ) { 00283 thr.Event(&incr); 00284 Sleep(100); 00285 } 00286 } 00287 cout << "\ndone\n"; 00288 00289 } 00290 00291