Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added boost

File size: 5.1 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 <boost/thread/mutex.hpp>
13#include <boost/thread/condition.hpp>
14#include <boost/thread/thread.hpp>
15#include <boost/thread/xtime.hpp>
16#include <iostream>
17#include <time.h>
18
19namespace
20{
21boost::mutex iomx;
22} // namespace
23
24class canteen
25{
26public:
27    canteen() : m_chickens(0) { }
28
29    void get(int id)
30    {
31        boost::mutex::scoped_lock lock(m_mutex);
32        while (m_chickens == 0)
33        {
34            {
35                boost::mutex::scoped_lock lock(iomx);
36                std::cout << "(" << clock() << ") Phil" << id <<
37                    ": wot, no chickens?  I'll WAIT ..." << std::endl;
38            }
39            m_condition.wait(lock);
40        }
41        {
42            boost::mutex::scoped_lock lock(iomx);
43            std::cout << "(" << clock() << ") Phil" << id <<
44                ": those chickens look good ... one please ..." << std::endl;
45        }
46        m_chickens--;
47    }
48    void put(int value)
49    {
50        boost::mutex::scoped_lock lock(m_mutex);
51        {
52            boost::mutex::scoped_lock lock(iomx);
53            std::cout << "(" << clock()
54                      << ") Chef: ouch ... make room ... this dish is "
55                      << "very hot ..." << std::endl;
56        }
57        boost::xtime xt;
58        boost::xtime_get(&xt, boost::TIME_UTC);
59        xt.sec += 3;
60        boost::thread::sleep(xt);
61        m_chickens += value;
62        {
63            boost::mutex::scoped_lock lock(iomx);
64            std::cout << "(" << clock() <<
65                ") Chef: more chickens ... " << m_chickens <<
66                " now available ... NOTIFYING ..." << std::endl;
67        }
68        m_condition.notify_all();
69    }
70
71private:
72    boost::mutex m_mutex;
73    boost::condition m_condition;
74    int m_chickens;
75};
76
77canteen g_canteen;
78
79void chef()
80{
81    const int chickens = 4;
82    {
83        boost::mutex::scoped_lock lock(iomx);
84        std::cout << "(" << clock() << ") Chef: starting ..." << std::endl;
85    }
86    for (;;)
87    {
88        {
89            boost::mutex::scoped_lock lock(iomx);
90            std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
91        }
92        boost::xtime xt;
93        boost::xtime_get(&xt, boost::TIME_UTC);
94        xt.sec += 2;
95        boost::thread::sleep(xt);
96        {
97            boost::mutex::scoped_lock lock(iomx);
98            std::cout << "(" << clock() << ") Chef: " << chickens
99                      << " chickens, ready-to-go ..." << std::endl;
100        }
101        g_canteen.put(chickens);
102    }
103}
104
105struct phil
106{
107    phil(int id) : m_id(id) { }
108    void run() {
109        {
110            boost::mutex::scoped_lock lock(iomx);
111            std::cout << "(" << clock() << ") Phil" << m_id
112                      << ": starting ..." << std::endl;
113        }
114        for (;;)
115        {
116            if (m_id > 0)
117            {
118                boost::xtime xt;
119                boost::xtime_get(&xt, boost::TIME_UTC);
120                xt.sec += 3;
121                boost::thread::sleep(xt);
122            }
123            {
124                boost::mutex::scoped_lock lock(iomx);
125                std::cout << "(" << clock() << ") Phil" << m_id
126                          << ": gotta eat ..." << std::endl;
127            }
128            g_canteen.get(m_id);
129            {
130                boost::mutex::scoped_lock lock(iomx);
131                std::cout << "(" << clock() << ") Phil" << m_id
132                          << ": mmm ... that's good ..." << std::endl;
133            }
134        }
135    }
136    static void do_thread(void* param) {
137        static_cast<phil*>(param)->run();
138    }
139
140    int m_id;
141};
142
143struct thread_adapt
144{
145    thread_adapt(void (*func)(void*), void* param)
146        : _func(func), _param(param)
147    {
148    }
149    int operator()() const
150    {
151        _func(_param);
152        return 0;
153    }
154
155    void (*_func)(void*);
156    void* _param;
157};
158
159class thread_adapter
160{
161public:
162    thread_adapter(void (*func)(void*), void* param)
163        : _func(func), _param(param)
164    {
165    }
166    void operator()() const { _func(_param); }
167private:
168    void (*_func)(void*);
169    void* _param;
170};
171
172int main(int argc, char* argv[])
173{
174    boost::thread thrd_chef(&chef);
175    phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };
176    boost::thread thrd_phil0(thread_adapter(&phil::do_thread, &p[0]));
177    boost::thread thrd_phil1(thread_adapter(&phil::do_thread, &p[1]));
178    boost::thread thrd_phil2(thread_adapter(&phil::do_thread, &p[2]));
179    boost::thread thrd_phil3(thread_adapter(&phil::do_thread, &p[3]));
180    boost::thread thrd_phil4(thread_adapter(&phil::do_thread, &p[4]));
181
182    thrd_chef.join();
183    thrd_phil0.join();
184    thrd_phil1.join();
185    thrd_phil2.join();
186    thrd_phil3.join();
187    thrd_phil4.join();
188
189    return 0;
190}
Note: See TracBrowser for help on using the repository browser.