Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * example_mutx_count.cpp - Example for counting with multiple threads and 00004 * protecting the count variable with a mutex 00005 * 00006 * Generated: Thu Sep 14 16:29:37 2006 00007 * Copyright 2006 Tim Niemueller [www.niemueller.de] 00008 * 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL file in the doc directory. 00022 */ 00023 00024 #include <core/threading/thread.h> 00025 #include <core/threading/mutex.h> 00026 00027 #include <iostream> 00028 00029 // By default do not include examples in API documentation 00030 /// @cond EXAMPLES 00031 00032 using namespace std; 00033 using namespace fawkes; 00034 00035 #define WASTETIME \ 00036 for ( unsigned int i = 0; i < 1000000; i++) { \ 00037 unsigned int j; \ 00038 j = i + i; \ 00039 } 00040 00041 00042 /** Simple test class for counting with multiple threads. 00043 * Compile the test program and let it run. You will see that even after only a short time 00044 * the values for the protected and the unprotected count variables differ. 00045 */ 00046 class ExampleMutexCountThread : public Thread 00047 { 00048 public: 00049 /** Constructor 00050 * @param s Short identifier, printed first in output 00051 * @param m The mutex used to protect count variable 00052 * @param mutex_count Protected count variable 00053 * @param non_mutex_count Unprotected count variable 00054 * @param sleep_time Variable sleep time at end of thread 00055 */ 00056 ExampleMutexCountThread(string s, 00057 Mutex *m, unsigned int *mutex_count, unsigned int *non_mutex_count, 00058 unsigned int sleep_time) 00059 : Thread("ExampMutexCountThread", Thread::OPMODE_CONTINUOUS) 00060 { 00061 this->s = s; 00062 this->sl = sl; 00063 this->slt = sleep_time; 00064 this->m = m; 00065 this->mc = mutex_count; 00066 this->nmc = non_mutex_count; 00067 } 00068 00069 /** Where the action happens 00070 */ 00071 virtual void loop() 00072 { 00073 // unprotected modification, another thread could modify the value while 00074 // we waste time 00075 unsigned int n = *nmc; 00076 n++; 00077 sleep(0); 00078 WASTETIME; 00079 *nmc = n; 00080 00081 // protected modification, no other thread can modify the value as long as 00082 // we have the lock 00083 if ( m != NULL ) m->lock(); 00084 unsigned o = *mc; 00085 o++; 00086 sleep(0); 00087 WASTETIME; 00088 *mc = o; 00089 if ( m != NULL ) m->unlock(); 00090 00091 // Out is not mutexed, can lead to wrong printouts, try it (happens rarely)! 00092 cout << s << ": mutex: " << *mc << "(non-mutex: " << *nmc << ")" << endl; 00093 00094 if ( sl ) usleep(slt); 00095 00096 test_cancel(); 00097 } 00098 00099 private: 00100 string s; 00101 bool sl; 00102 unsigned int slt; 00103 Mutex *m; 00104 unsigned int *mc; 00105 unsigned int *nmc; 00106 }; 00107 00108 00109 int 00110 main(int argc, char **argv) 00111 { 00112 00113 Mutex *m = new Mutex(); 00114 00115 unsigned int mutex_count = 0; 00116 unsigned int non_mutex_count = 0; 00117 00118 ExampleMutexCountThread *t1 = new ExampleMutexCountThread("t1", m, &mutex_count, &non_mutex_count, 1000); 00119 ExampleMutexCountThread *t2 = new ExampleMutexCountThread("t2", m, &mutex_count, &non_mutex_count, 10000); 00120 ExampleMutexCountThread *t3 = new ExampleMutexCountThread("t3", m, &mutex_count, &non_mutex_count, 100000); 00121 00122 t1->start(); 00123 t2->start(); 00124 t3->start(); 00125 00126 // Wait for all threads to finish 00127 t1->join(); 00128 t2->join(); 00129 t3->join(); 00130 00131 delete t1; 00132 delete t2; 00133 delete t3; 00134 delete m; 00135 } 00136 00137 00138 /// @endcond