-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathThreadPool.hpp
85 lines (81 loc) · 1.83 KB
/
ThreadPool.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
#ifndef THREADPOOL_HPP
#define THREADPOOL_HPP
#include <cstdint>
#include <mutex>
#include <thread>
#include <functional>
#include <future>
#include <condition_variable>
#include<queue>
#include <iostream>
using namespace std;
class ThreadPool
{
private:
vector<thread> workers;
queue<function<void()>> jobs;
mutex m;
condition_variable cv;
bool stop;
public:
ThreadPool(int = 4);
~ThreadPool();
template <class F, class... Args>
future<invoke_result_t<F,Args...>> submit(F &&f, Args &&...args);
void shutdown();
};
ThreadPool::ThreadPool(int max_workers) : stop(false)
{
for (int i = 0; i < max_workers; i++)
{
thread worker([&]
{
while(1){
unique_lock<mutex> lk(m);
cv.wait(lk,[&]{return stop||!jobs.empty();});
if(stop&&jobs.empty())return;
auto run=jobs.front();
jobs.pop();
lk.unlock();
run();
} });
workers.emplace_back(std::move(worker));
}
}
template <class F, class... Args>
future<invoke_result_t<F,Args...>> ThreadPool::submit(F &&f, Args &&...args)
{
using ret_type=invoke_result_t<F,Args...>;
auto task = make_shared<packaged_task<ret_type()>>(bind(forward<F>(f), forward<Args>(args)...));
future<ret_type> fut=task->get_future();
{
unique_lock<mutex> lk(m);
if (stop)
{
cout << "ThreadPool has stopped.\n";
}
jobs.push([task]()
{ (*task)(); });
}
cv.notify_one();
return fut;
}
void ThreadPool::shutdown()
{
{
unique_lock<mutex> lk(m);
stop = 1;
}
cv.notify_all();
for (thread &worker : workers)
{
if (worker.joinable())
worker.join();
}
}
ThreadPool::~ThreadPool()
{
if (!stop)
shutdown();
}
#endif