source: Sophya/trunk/SophyaExt/JThreadsC++/Examples/diner.cc@ 4072

Last change on this file since 4072 was 1016, checked in by ansari, 25 years ago

Creation du module JThreadsC++, importation du code des classes
de Thread a la Java de Object Oriented Concepts Inc - Reza 19/5/2000

File size: 6.5 KB
Line 
1// **********************************************************************
2//
3// Copyright (c) 2000
4// Object Oriented Concepts, Inc.
5// Billerica, MA, USA
6//
7// All Rights Reserved
8//
9// **********************************************************************
10
11#include <JTC/JTC.h>
12
13#include <stdlib.h>
14
15#if defined(HAVE_STRSTREAM)
16# include <strstream>
17#else
18# if defined(HAVE_STRSTREA_H)
19# include <strstrea.h>
20# else
21# include <strstream.h>
22# endif
23#endif
24
25#ifdef HAVE_STD_IOSTREAM
26using namespace std;
27#endif
28
29//
30// This class ensures that the iostream class is only accessed by one
31// thread. This stops corruption of the output stream.
32//
33class MTCout : public JTCMonitor
34{
35public:
36
37 void write(const char* buf)
38 {
39 JTCSynchronized sync(*this);
40 cout << buf << endl;
41 }
42};
43
44//
45// Global instance of the MTCout object.
46//
47MTCout mtCout;
48
49//
50// This class returns a random number.
51//
52class Random : public JTCMonitor
53{
54public:
55
56 int operator()()
57 {
58 JTCSynchronized sync(*this);
59 return rand();
60 }
61};
62
63//
64// Global instance of the random object.
65//
66Random genRandom;
67
68//
69// This class represents a chopstick.
70//
71class Chopstick : public JTCMonitor
72{
73};
74
75//
76// We have N_DINERS diners, and N_DINERS chopsticks.
77//
78#define N_DINERS 5
79Chopstick chopsticks[N_DINERS];
80
81//
82// A room.
83//
84class Room : public JTCMonitor
85{
86 int occupancy_; // Number of people in the room.
87 int maxOccupancy_; // Maximum number of people allowed in the room.
88public:
89 //
90 // Constructor.
91 //
92 Room(int maxOccupancy)
93 : occupancy_(0), maxOccupancy_(maxOccupancy)
94 {
95 }
96
97 //
98 // Add a person to the room.
99 //
100 void addPerson()
101 {
102 JTCSynchronized sync(*this);
103 ++occupancy_;
104 notifyAll();
105 }
106
107 //
108 // Remove a person from the room.
109 //
110 void removePerson()
111 {
112 JTCSynchronized sync(*this);
113 --occupancy_;
114 notifyAll();
115 }
116
117 //
118 // Wait for a place to become available.
119 //
120 void waitForPlace()
121 {
122 JTCSynchronized sync(*this);
123 while(occupancy_ == maxOccupancy_)
124 {
125 try
126 {
127 wait();
128 }
129 catch(const JTCInterruptedException&)
130 {
131 }
132 }
133 }
134
135 //
136 // Get the number of people in the room.
137 //
138 int numberPeople()
139 {
140 JTCSynchronized sync(*this);
141 return occupancy_;
142 }
143};
144
145Room room(N_DINERS);
146
147class Philosopher;
148
149//
150// Array of philosopher threads.
151//
152bool phillies[N_DINERS];
153
154//
155// This class represents a hungry philosopher.
156//
157class Philosopher : public JTCThread
158{
159 int id_; // The id of the philosopher.
160
161public:
162
163 //
164 // Constructor.
165 //
166 Philosopher(int id)
167 : id_(id)
168 {
169 }
170
171 //
172 // Mainline. Grab left chopstick, grab right chopstick. Eat food.
173 // Ponder life for a while. Put down the chopsticks, and sleep for
174 // a while. Repeat this cycle some random number of times.
175 // Then exit the room.
176 //
177 virtual void run()
178 {
179 //
180 // The variables l and r represent the index of the left and
181 // right chopsticks around the table.
182 //
183 int l = id_;
184 int r = l+1;
185 if(r == N_DINERS)
186 {
187 r = 0;
188 }
189 if(l & 1)
190 {
191 int t = l;
192 l = r;
193 r = t;
194 }
195 char buf[1024];
196 ostrstream os(buf, sizeof(buf));
197
198 os << "Philosopher #" << id_ << " has entered the room." <<ends;
199 mtCout.write(buf);
200 os.seekp(0);
201
202 int count = genRandom() % 10 + 1;
203 while(count--)
204 {
205 {
206 //
207 // Grab left and right chopstick.
208 //
209 JTCSynchronized sync1(chopsticks[l]);
210 JTCSynchronized sync2(chopsticks[r]);
211
212 //
213 // Eat.
214 //
215 os << "Philosopher #" << id_ << " is eating." << ends;
216 mtCout.write(buf);
217 os.seekp(0);
218
219 //
220 // Ponder life.
221 //
222 JTCThread::sleep(genRandom()%2*1000 + genRandom()%1000);
223 os << "Philosopher #" << id_ << " is pondering life."<<ends;
224 mtCout.write(buf);
225 os.seekp(0);
226 }
227 //
228 // Sleep for some period, before starting over.
229 //
230 JTCThread::sleep(genRandom()%2*1000 + genRandom()%1000);
231 }
232
233 //
234 // Remove the philosopher from the room.
235 //
236 room.removePerson();
237
238 //
239 // Clear a spot in the array for the next philosopher.
240 //
241 phillies[id_] = false;
242
243 JTCSynchronized mtSync(mtCout);
244 os << "Philosopher #" << id_ << " has left the room. ("
245 << room.numberPeople() << " left)." << ends;
246 mtCout.write(buf);
247 os.seekp(0);
248 }
249};
250
251int
252main(int argc, char** argv)
253{
254
255 try
256 {
257 //
258 // A user of the JTC library must create an instance of this
259 // class to initialize the library.
260 //
261 JTCInitialize bootJTC(argc, argv);
262
263 //
264 // Number of philosophers waiting to enter the room
265 // after the initial N_DINERS.
266 //
267 // Once all the diners have left the room the application
268 // will exit.
269 //
270 int nInQ = -1;
271 if (argc > 1)
272 {
273 nInQ = atoi(argv[1]);
274 }
275
276 //
277 // Seed the random number generator.
278 //
279 srand(0);
280
281 int i;
282
283 //
284 // Add N_DINERS to the room.
285 //
286 for(i =0; i < N_DINERS; ++i)
287 {
288 room.addPerson();
289 phillies[i] = true;
290 JTCThreadHandle p = new Philosopher(i);
291 p -> start();
292 }
293
294 //
295 // Repeat forever.
296 //
297 while (nInQ > 0 || nInQ == -1)
298 {
299 //
300 // Wait for a place to open up in the room.
301 //
302 room.waitForPlace();
303 mtCout.write("main thread sleep.");
304
305 JTCThread::sleep(3);
306 mtCout.write("main thread wake.");
307
308 //
309 // Find the location of the philospher that left the room.
310 //
311 for(i =0; i < N_DINERS; ++i)
312 if(!phillies[i])
313 break;
314
315 //
316 // Can't find the location? This is an internal error of
317 // some sort.
318 //
319 if(i == N_DINERS)
320 abort();
321 //
322 // Create a new philosopher thread, add a person to the room.
323 //
324 room.addPerson();
325
326 phillies[i] = true;
327
328 JTCThreadHandle p = new Philosopher(i);
329 p -> start();
330
331 if (nInQ != -1)
332 {
333 --nInQ;
334 }
335 }
336 }
337 catch(const JTCException& e)
338 {
339 cout << "Exception: " << e.getMessage() << endl;
340 return EXIT_FAILURE;
341 }
342
343 return EXIT_SUCCESS;
344}
345
Note: See TracBrowser for help on using the repository browser.