/
executor.hpp
114 lines (105 loc) · 2.37 KB
/
executor.hpp
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
#ifndef __EXECUTOR_H__
#define __EXECUTOR_H__
#include "sftool.h"
#include <deque>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/lockfree/queue.hpp>
#include <boost/atomic.hpp>
SFTOOL_NAMESPACE_START
template<typename T>
class executor {
public:
typedef boost::shared_ptr<T> TaskPtr;
typedef boost::shared_ptr<boost::thread> ThreadPtr;
executor(int size) {
_running = true;
for (int i = 0; i < size; ++i) {
_threads.push_back(
ThreadPtr(new boost::thread(&executor::_exec, this)));
}
}
~executor() {
_running = false;
_tasks.clear();
_no_task.notify_all();
join();
}
void execute(const boost::shared_ptr<T>& task) {
push(task);
}
void shutdown() {
_running = false;
_no_task.notify_all();
}
void join() {
for (std::list<ThreadPtr>::iterator it = _threads.begin();
it != _threads.end(); ++it) {
(*it)->join();
}
std::cout << "Joined all threads." << std::endl;
}
static void _exec(executor* exec) {
while (true) {
TaskPtr task = exec->pull();
if (task) {
task->run();
continue;
}
if (!exec->_running) {
std::cout << "Finished running all task " << exec << std::endl;
return;
}
};
}
private:
boost::atomic<bool> _running;
std::deque<TaskPtr> _tasks;
std::list<ThreadPtr> _threads;
boost::mutex _mutex;
boost::condition_variable _no_task;
TaskPtr pull() {
boost::unique_lock<boost::mutex> lock(_mutex);
while (_running) {
std::cout << "pull 0" << std::endl;
if (!_tasks.empty()) {
std::cout << "pull A" << std::endl;
TaskPtr task = _tasks.front();
_tasks.pop_front();
return task;
} else {
std::cout << "pull B" << std::endl;
_no_task.wait(lock);
std::cout << "pull C" << std::endl;
}
}
while (!_running) {
std::cout << "pull 1" << std::endl;
if (!_tasks.empty()) {
std::cout << "pull D" << std::endl;
TaskPtr task = _tasks.front();
_tasks.pop_front();
return task;
} else {
std::cout << "pull E" << std::endl;
return TaskPtr();
}
}
return TaskPtr();
}
void push(const TaskPtr& task) {
if (!_running) {
return;
}
boost::unique_lock<boost::mutex> lock(_mutex);
std::cout << "push A" << std::endl;
_tasks.push_back(task);
if (_tasks.size() >= 1) {
std::cout << "push B" << std::endl;
_no_task.notify_one();
std::cout << "push C" << std::endl;
}
}
};
SFTOOL_NAMESPACE_END
#endif