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
7#include <vector>
8#include <iostream>
9#include <boost/thread/condition_variable.hpp>
10#include <boost/thread/mutex.hpp>
11#include <boost/thread/recursive_mutex.hpp>
12#include <boost/thread/thread_only.hpp>
13
14namespace {
15const int ITERS = 100;
16boost::mutex io_mutex;
17} // namespace
18
19template <typename M>
20class buffer_t
21{
22public:
23 typedef boost::unique_lock<M> scoped_lock;
24
25 buffer_t(int n)
26 : p(0), c(0), full(0), buf(n)
27 {
28 }
29
30 void send(int m)
31 {
32 scoped_lock lk(mutex);
33 while (full == buf.size())
34 cond.wait(lk);
35 buf[p] = m;
36 p = (p+1) % buf.size();
37 ++full;
38 cond.notify_one();
39 }
40 int receive()
41 {
42 scoped_lock lk(mutex);
43 while (full == 0)
44 cond.wait(lk);
45 int i = buf[c];
46 c = (c+1) % buf.size();
47 --full;
48 cond.notify_one();
49 return i;
50 }
51
52 static buffer_t& get_buffer()
53 {
54 static buffer_t buf(2);
55 return buf;
56 }
57
58 static void do_sender_thread()
59 {
60 for (int n = 0; n < ITERS; ++n)
61 {
62 {
63 boost::unique_lock<boost::mutex> lock(io_mutex);
64 std::cout << "sending: " << n << std::endl;
65 }
66 get_buffer().send(n);
67 }
68 }
69
70 static void do_receiver_thread()
71 {
72 for (int x=0; x < (ITERS/2); ++x)
73 {
74 int n = get_buffer().receive();
75 {
76 boost::unique_lock<boost::mutex> lock(io_mutex);
77 std::cout << "received: " << n << std::endl;
78 }
79 }
80 }
81
82private:
83 M mutex;
84 boost::condition_variable_any cond;
85 unsigned int p, c, full;
86 std::vector<int> buf;
87};
88
89template <typename M>
90void do_test(M* dummy=0)
91{
92 (void)dummy;
93 typedef buffer_t<M> buffer_type;
94 buffer_type::get_buffer();
95 boost::thread thrd1(&buffer_type::do_receiver_thread);
96 boost::thread thrd2(&buffer_type::do_receiver_thread);
97 boost::thread thrd3(&buffer_type::do_sender_thread);
98 thrd1.join();
99 thrd2.join();
100 thrd3.join();
101}
102
103void test_buffer()
104{
105 do_test<boost::mutex>();
106 do_test<boost::recursive_mutex>();
107}
108
109int main()
110{
111 test_buffer();
112 return 0;
113}
114

source code of boost/libs/thread/example/monitor.cpp