Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/example/monitor.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 2.6 KB
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4// Permission to use, copy, modify, distribute and sell this software
5// and its documentation for any purpose is hereby granted without fee,
6// provided that the above copyright notice appear in all copies and
7// that both that copyright notice and this permission notice appear
8// in supporting documentation.  William E. Kempf makes no representations
9// about the suitability of this software for any purpose.
10// It is provided "as is" without express or implied warranty.
11
12#include <vector>
13#include <iostream>
14#include <boost/thread/condition.hpp>
15#include <boost/thread/mutex.hpp>
16#include <boost/thread/recursive_mutex.hpp>
17#include <boost/thread/thread.hpp>
18
19namespace {
20const int ITERS = 100;
21boost::mutex io_mutex;
22} // namespace
23
24template <typename M>
25class buffer_t
26{
27public:
28    typedef typename M::scoped_lock scoped_lock;
29
30    buffer_t(int n)
31        : p(0), c(0), full(0), buf(n)
32    {
33    }
34
35    void send(int m)
36    {
37        scoped_lock lk(mutex);
38        while (full == buf.size())
39            cond.wait(lk);
40        buf[p] = m;
41        p = (p+1) % buf.size();
42        ++full;
43        cond.notify_one();
44    }
45    int receive()
46    {
47        scoped_lock lk(mutex);
48        while (full == 0)
49            cond.wait(lk);
50        int i = buf[c];
51        c = (c+1) % buf.size();
52        --full;
53        cond.notify_one();
54        return i;
55    }
56
57    static buffer_t& get_buffer()
58    {
59        static buffer_t buf(2);
60        return buf;
61    }
62
63    static void do_sender_thread()
64    {
65        for (int n = 0; n < ITERS; ++n)
66        {
67            {
68                boost::mutex::scoped_lock lock(io_mutex);
69                std::cout << "sending: " << n << std::endl;
70            }
71            get_buffer().send(n);
72        }
73    }
74
75    static void do_receiver_thread()
76    {
77        for (int x=0; x < (ITERS/2); ++x)
78        {
79            int n = get_buffer().receive();
80            {
81                boost::mutex::scoped_lock lock(io_mutex);
82                std::cout << "received: " << n << std::endl;
83            }
84        }
85    }
86
87private:
88    M mutex;
89    boost::condition cond;
90    unsigned int p, c, full;
91    std::vector<int> buf;
92};
93
94template <typename M>
95void do_test(M* dummy=0)
96{
97    typedef buffer_t<M> buffer_type;
98    buffer_type::get_buffer();
99    boost::thread thrd1(&buffer_type::do_receiver_thread);
100    boost::thread thrd2(&buffer_type::do_receiver_thread);
101    boost::thread thrd3(&buffer_type::do_sender_thread);
102    thrd1.join();
103    thrd2.join();
104    thrd3.join();
105}
106
107void test_buffer()
108{
109    do_test<boost::mutex>();
110    do_test<boost::recursive_mutex>();
111}
112
113int main()
114{
115    test_buffer();
116    return 0;
117}
Note: See TracBrowser for help on using the repository browser.