Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/thread/example/starvephil.cpp @ 35

Last change on this file since 35 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

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