]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blob - tests/oo_thread.cpp
Se completa un poco mas el manual del proyecto.
[z.facultad/75.42/plaqui.git] / tests / oo_thread.cpp
1 // Callbacks in C++
2 // Refer to http://www.cscene.org for detailed docs.
3 //
4 // Copyright (c) 1998 by Juergen Hermann
5 //
6 // To make things easy, we put all code in one file.
7 // Large parts of this should go to thread.hpp/cpp in real real life.
8
9 #include <cstdlib>
10 #include <ctime>
11 #include <cassert>
12 #include <string>
13 #include <iostream>
14 #include <pthread.h>
15 #include <unistd.h>
16
17 ///////////////////////////////////////////////////////////////////////
18 // Utility stuff
19 ///////////////////////////////////////////////////////////////////////
20
21 inline int randrange(int lo, int hi)
22 {
23     return rand() / (RAND_MAX / (hi - lo + 1)) + lo;
24 }
25
26
27 ///////////////////////////////////////////////////////////////////////
28 // A thread base class
29 ///////////////////////////////////////////////////////////////////////
30
31 class Thread {
32 public:
33     virtual ~Thread() {}
34     void run();
35     pthread_t get_thread() const { return thread; }
36
37 protected:
38     Thread();
39     virtual void code() = 0;
40
41 private:
42     int running;
43     pthread_t thread;
44
45     static void* dispatch(void* thread_obj);
46 };
47
48
49 Thread::Thread() 
50     : running(0) 
51 {
52 }
53
54
55 void Thread::run()
56 {
57     // Don't start two threads on the same object
58     if (running) return;
59
60     // Create an OS thread, using the static callback
61     assert(!pthread_create(&thread, NULL, Thread::dispatch, static_cast<void*>(this)));
62     pthread_detach(thread);
63     running = 1;
64 }
65
66
67 void* Thread::dispatch(void* thread_obj)
68 {
69     // Call the actual OO thread code
70     static_cast<Thread*>(thread_obj)->code();
71
72     // After code() returns, kill the thread object
73     delete static_cast<Thread*>(thread_obj);
74
75     return NULL;
76 }
77
78
79 ///////////////////////////////////////////////////////////////////////
80 // An example thread class
81 ///////////////////////////////////////////////////////////////////////
82
83 class Dice : private Thread {
84 public:
85     static void Dice::create(const char* dicename);
86     //static CRITICAL_SECTION sync;
87
88 private:
89     Dice(const char* dicename) : name(dicename) {}
90     virtual void code();
91
92     std::string name;
93 };
94
95
96 //CRITICAL_SECTION Dice::sync;
97
98
99 void Dice::create(const char* dicename)
100 {
101     (new Dice(dicename))->run();
102 }
103
104
105 void Dice::code()
106 {
107     //EnterCriticalSection(&sync);
108     std::cout << "Started thread #" << static_cast<unsigned long>(get_thread())
109             << " for " << name << std::endl;
110     //LeaveCriticalSection(&sync);
111
112     srand(time(0) * get_thread());
113
114     for (;;) {
115         int val = randrange(1, 6);
116
117         //EnterCriticalSection(&sync);
118         std::cout << name << " rolled " << val << std::endl;
119         //LeaveCriticalSection(&sync);
120
121         sleep(randrange(0, 1)); // wait up to 1 sec
122     }
123 }
124
125
126 ///////////////////////////////////////////////////////////////////////
127 // Let's test!
128 ///////////////////////////////////////////////////////////////////////
129
130 int main()
131 {
132     //InitializeCriticalSection(&Dice::sync);
133
134     Dice::create("dice1");
135     Dice::create("dice2");
136
137     sleep(10); // roll dice for 10 seconds
138         
139     return 0; // cleanup? what's cleanup?
140 }