Fawkes API  Fawkes Development Version
qa_mutex_count.cpp
1 
2 /***************************************************************************
3  * example_mutx_count.cpp - Example for counting with multiple threads and
4  * protecting the count variable with a mutex
5  *
6  * Generated: Thu Sep 14 16:29:37 2006
7  * Copyright 2006 Tim Niemueller [www.niemueller.de]
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL file in the doc directory.
22  */
23 
24 #include <core/threading/mutex.h>
25 #include <core/threading/thread.h>
26 
27 #include <iostream>
28 
29 // By default do not include examples in API documentation
30 /// @cond EXAMPLES
31 
32 using namespace std;
33 using namespace fawkes;
34 
35 #define WASTETIME \
36  for (unsigned int i = 0; i < 1000000; i++) { \
37  unsigned int j; \
38  j = i + i; \
39  }
40 
41 /** Simple test class for counting with multiple threads.
42  * Compile the test program and let it run. You will see that even after only a short time
43  * the values for the protected and the unprotected count variables differ.
44  */
45 class ExampleMutexCountThread : public Thread
46 {
47 public:
48  /** Constructor
49  * @param s Short identifier, printed first in output
50  * @param m The mutex used to protect count variable
51  * @param mutex_count Protected count variable
52  * @param non_mutex_count Unprotected count variable
53  * @param sleep_time Variable sleep time at end of thread
54  */
55  ExampleMutexCountThread(string s,
56  Mutex * m,
57  unsigned int *mutex_count,
58  unsigned int *non_mutex_count,
59  unsigned int sleep_time)
60  : Thread("ExampMutexCountThread", Thread::OPMODE_CONTINUOUS)
61  {
62  this->s = s;
63  this->sl = sl;
64  this->slt = sleep_time;
65  this->m = m;
66  this->mc = mutex_count;
67  this->nmc = non_mutex_count;
68  }
69 
70  /** Where the action happens
71  */
72  virtual void
73  loop()
74  {
75  // unprotected modification, another thread could modify the value while
76  // we waste time
77  unsigned int n = *nmc;
78  n++;
79  sleep(0);
80  WASTETIME;
81  *nmc = n;
82 
83  // protected modification, no other thread can modify the value as long as
84  // we have the lock
85  if (m != NULL)
86  m->lock();
87  unsigned o = *mc;
88  o++;
89  sleep(0);
90  WASTETIME;
91  *mc = o;
92  if (m != NULL)
93  m->unlock();
94 
95  // Out is not mutexed, can lead to wrong printouts, try it (happens rarely)!
96  cout << s << ": mutex: " << *mc << "(non-mutex: " << *nmc << ")" << endl;
97 
98  if (sl)
99  usleep(slt);
100 
101  test_cancel();
102  }
103 
104 private:
105  string s;
106  bool sl;
107  unsigned int slt;
108  Mutex * m;
109  unsigned int *mc;
110  unsigned int *nmc;
111 };
112 
113 int
114 main(int argc, char **argv)
115 {
116  Mutex *m = new Mutex();
117 
118  unsigned int mutex_count = 0;
119  unsigned int non_mutex_count = 0;
120 
121  ExampleMutexCountThread *t1 =
122  new ExampleMutexCountThread("t1", m, &mutex_count, &non_mutex_count, 1000);
123  ExampleMutexCountThread *t2 =
124  new ExampleMutexCountThread("t2", m, &mutex_count, &non_mutex_count, 10000);
125  ExampleMutexCountThread *t3 =
126  new ExampleMutexCountThread("t3", m, &mutex_count, &non_mutex_count, 100000);
127 
128  t1->start();
129  t2->start();
130  t3->start();
131 
132  // Wait for all threads to finish
133  t1->join();
134  t2->join();
135  t3->join();
136 
137  delete t1;
138  delete t2;
139  delete t3;
140  delete m;
141 }
142 
143 /// @endcond
fawkes::Mutex
Mutex mutual exclusion lock.
Definition: mutex.h:33
fawkes
Fawkes library namespace.
fawkes::Thread
Thread class encapsulation of pthreads.
Definition: thread.h:46