-
Notifications
You must be signed in to change notification settings - Fork 2
/
test.cpp
117 lines (114 loc) · 3.28 KB
/
test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <iostream>
#include <vector>
#include "SimpleThread.h"
using namespace std;
typedef enum{
INIT,
RUNNING,
STOP
} ThreadState;
//runnable class
class MyRunnable : public Runnable {
private:
mutex mmutex;
Condition *condition;
ThreadState requestedState=INIT;
ThreadState currentState=INIT;
int id;
public:
MyRunnable(int id){
this->id=id;
condition=new Condition(mmutex);
}
~MyRunnable(){
delete condition;
}
int getId(){
return id;
}
void setState(ThreadState nState){
{
Synchronized x(mmutex);
requestedState=nState;
condition->notifyAll(x);
}
};
ThreadState getState(){
Synchronized x(mmutex);
return currentState;
};
virtual void run() {
{
Synchronized x(mmutex);
currentState=RUNNING;
}
cout << "Thread "<<id<<" started" << endl;
while(true){
{
Synchronized x(mmutex);
if (requestedState==STOP){
currentState=STOP;
cout << "stopping thread "<<id<<endl;
return;
}
condition->wait(x,1000);
}
cout << "hello thread " <<id<< endl;
}
}
};
int main(int argc, char ** argv){
cout << "hello world" << endl;
int numThreads=5;
if (argc > 1){
numThreads=atoi(argv[1]);
}
vector<MyRunnable*> runnables;
for (int i=0;i< numThreads;i++){
MyRunnable *runnable=new MyRunnable(i);
Thread *t=new Thread(runnable);
t->start();
runnables.push_back(runnable);
}
//"misuse" of a condition for ms waits
Condition waiter;
//waiting for start
bool allRunning=false;
cout << "waiting for threads to start" << endl;
while (! allRunning){
allRunning=true;
vector<MyRunnable*>::iterator it=runnables.begin();
while (it != runnables.end()){
if ((*it)->getState() != RUNNING) {
cout << "##state "<<((*it)->getId())<<" is "<<((*it)->getState())<<endl;
allRunning=false;
}
it++;
}
waiter.wait(20); //avoid busy loop
}
cout << numThreads << " are running" <<endl;
waiter.wait(10000);
cout << "stopping" << endl;
vector<MyRunnable*>::iterator it=runnables.begin();
while (it != runnables.end()){
(*it)->setState(STOP);
it++;
}
bool allStopped=false;
int maxWait=50*10; //max 10s
while (! allStopped && maxWait){
allStopped=true;
vector<MyRunnable*>::iterator it=runnables.begin();
while (it != runnables.end()){
if ((*it)->getState() != STOP) allStopped=false;
it++;
}
maxWait--;
waiter.wait(20); //avoid busy loop
}
if (allStopped) cout << "all threads stopped" << endl;
else cout << "unable to stop all threads" << endl;
//if we would like to wait here for all threads
//we also would need to keep the thread objects...
};