monitor.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (C) 2001-2003
  2. // William E. Kempf
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <vector>
  7. #include <iostream>
  8. #include <boost/thread/condition_variable.hpp>
  9. #include <boost/thread/mutex.hpp>
  10. #include <boost/thread/recursive_mutex.hpp>
  11. #include <boost/thread/thread_only.hpp>
  12. namespace {
  13. const int ITERS = 100;
  14. boost::mutex io_mutex;
  15. } // namespace
  16. template <typename M>
  17. class buffer_t
  18. {
  19. public:
  20. typedef boost::unique_lock<M> scoped_lock;
  21. buffer_t(int n)
  22. : p(0), c(0), full(0), buf(n)
  23. {
  24. }
  25. void send(int m)
  26. {
  27. scoped_lock lk(mutex);
  28. while (full == buf.size())
  29. cond.wait(lk);
  30. buf[p] = m;
  31. p = (p+1) % buf.size();
  32. ++full;
  33. cond.notify_one();
  34. }
  35. int receive()
  36. {
  37. scoped_lock lk(mutex);
  38. while (full == 0)
  39. cond.wait(lk);
  40. int i = buf[c];
  41. c = (c+1) % buf.size();
  42. --full;
  43. cond.notify_one();
  44. return i;
  45. }
  46. static buffer_t& get_buffer()
  47. {
  48. static buffer_t buf(2);
  49. return buf;
  50. }
  51. static void do_sender_thread()
  52. {
  53. for (int n = 0; n < ITERS; ++n)
  54. {
  55. {
  56. boost::unique_lock<boost::mutex> lock(io_mutex);
  57. std::cout << "sending: " << n << std::endl;
  58. }
  59. get_buffer().send(n);
  60. }
  61. }
  62. static void do_receiver_thread()
  63. {
  64. for (int x=0; x < (ITERS/2); ++x)
  65. {
  66. int n = get_buffer().receive();
  67. {
  68. boost::unique_lock<boost::mutex> lock(io_mutex);
  69. std::cout << "received: " << n << std::endl;
  70. }
  71. }
  72. }
  73. private:
  74. M mutex;
  75. boost::condition_variable_any cond;
  76. unsigned int p, c, full;
  77. std::vector<int> buf;
  78. };
  79. template <typename M>
  80. void do_test(M* dummy=0)
  81. {
  82. (void)dummy;
  83. typedef buffer_t<M> buffer_type;
  84. buffer_type::get_buffer();
  85. boost::thread thrd1(&buffer_type::do_receiver_thread);
  86. boost::thread thrd2(&buffer_type::do_receiver_thread);
  87. boost::thread thrd3(&buffer_type::do_sender_thread);
  88. thrd1.join();
  89. thrd2.join();
  90. thrd3.join();
  91. }
  92. void test_buffer()
  93. {
  94. do_test<boost::mutex>();
  95. do_test<boost::recursive_mutex>();
  96. }
  97. int main()
  98. {
  99. test_buffer();
  100. return 0;
  101. }