Fawkes API Fawkes Development Version

qa_mutex_count.cpp

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
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends