shared_monitor.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (C) 2012 Vicente J. Botet Escriba
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <iostream>
  6. #include <boost/thread/mutex.hpp>
  7. #include <boost/thread/shared_mutex.hpp>
  8. #include <boost/thread/lock_algorithms.hpp>
  9. #include <boost/thread/thread_only.hpp>
  10. #if defined BOOST_THREAD_DONT_USE_CHRONO
  11. #include <boost/chrono/chrono_io.hpp>
  12. #endif
  13. #include <cassert>
  14. #include <vector>
  15. #define EXCLUSIVE 1
  16. #define SHARED 2
  17. #define MODE SHARED
  18. class A
  19. {
  20. #if MODE == EXCLUSIVE
  21. typedef boost::mutex mutex_type;
  22. #elif MODE == SHARED
  23. typedef boost::shared_mutex mutex_type;
  24. #else
  25. #error MODE not set
  26. #endif
  27. typedef std::vector<double> C;
  28. mutable mutex_type mut_;
  29. C data_;
  30. public:
  31. A() : data_(10000000) {}
  32. A(const A& a);
  33. A& operator=(const A& a);
  34. void compute(const A& x, const A& y);
  35. };
  36. A::A(const A& a)
  37. {
  38. #if MODE == EXCLUSIVE
  39. boost::unique_lock<mutex_type> lk(a.mut_);
  40. #elif MODE == SHARED
  41. boost::shared_lock<mutex_type> lk(a.mut_);
  42. #else
  43. #error MODE not set
  44. #endif
  45. data_ = a.data_;
  46. }
  47. A&
  48. A::operator=(const A& a)
  49. {
  50. if (this != &a)
  51. {
  52. boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
  53. #if MODE == EXCLUSIVE
  54. boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
  55. #elif MODE == SHARED
  56. boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
  57. #else
  58. #error MODE not set
  59. #endif
  60. boost::lock(lk1, lk2);
  61. data_ = a.data_;
  62. }
  63. return *this;
  64. }
  65. void
  66. A::compute(const A& x, const A& y)
  67. {
  68. boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
  69. #if MODE == EXCLUSIVE
  70. boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
  71. boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
  72. #elif MODE == SHARED
  73. boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
  74. boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
  75. #else
  76. #error MODE not set
  77. #endif
  78. boost::lock(lk1, lk2, lk3);
  79. assert(data_.size() == x.data_.size());
  80. assert(data_.size() == y.data_.size());
  81. for (unsigned i = 0; i < data_.size(); ++i)
  82. data_[i] = (x.data_[i] + y.data_[i]) / 2;
  83. }
  84. A a1;
  85. A a2;
  86. void test_s()
  87. {
  88. A la3 = a1;
  89. for (int i = 0; i < 150; ++i)
  90. {
  91. la3.compute(a1, a2);
  92. }
  93. }
  94. void test_w()
  95. {
  96. A la3 = a1;
  97. for (int i = 0; i < 10; ++i)
  98. {
  99. la3.compute(a1, a2);
  100. a1 = la3;
  101. a2 = la3;
  102. #if defined BOOST_THREAD_DONT_USE_CHRONO
  103. boost::this_thread::sleep_for(boost::chrono::seconds(1));
  104. #endif
  105. }
  106. }
  107. int main()
  108. {
  109. #if defined BOOST_THREAD_DONT_USE_CHRONO
  110. typedef boost::chrono::high_resolution_clock Clock;
  111. typedef boost::chrono::duration<double> sec;
  112. Clock::time_point t0 = Clock::now();
  113. #endif
  114. std::vector<boost::thread*> v;
  115. boost::thread thw(test_w);
  116. v.push_back(&thw);
  117. boost::thread thr0(test_w);
  118. v.push_back(&thr0);
  119. boost::thread thr1(test_w);
  120. v.push_back(&thr1);
  121. boost::thread thr2(test_w);
  122. v.push_back(&thr2);
  123. boost::thread thr3(test_w);
  124. v.push_back(&thr3);
  125. for (std::size_t i = 0; i < v.size(); ++i)
  126. v[i]->join();
  127. #if defined BOOST_THREAD_DONT_USE_CHRONO
  128. Clock::time_point t1 = Clock::now();
  129. std::cout << sec(t1-t0) << '\n';
  130. #endif
  131. return 0;
  132. }