emilib
thread_pool.hpp
1 // By Emil Ernerfeldt 2016
2 // LICENSE:
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 
7 #pragma once
8 
9 #include <condition_variable>
10 #include <deque>
11 #include <functional>
12 #include <future>
13 #include <memory>
14 #include <mutex>
15 #include <thread>
16 #include <vector>
17 
18 namespace emilib {
19 
21 {
22 public:
23  using Job = std::function<void()>;
24 
26  ThreadPool();
27 
29  explicit ThreadPool(size_t num_threads);
30 
32  ~ThreadPool();
33 
35  void wait();
36 
38  void clear();
39 
41  void add_void(const Job& job);
42 
44  template<typename Result>
45  std::future<Result> add(std::function<Result()> job)
46  {
47  const auto promise = std::make_shared<std::promise<Result>>();
48  std::future<Result> future = promise->get_future();
49  add_void([=]() {
50  promise->set_value(job());
51  });
52  return future;
53  }
54 
55  // TODO: add way to add jobs to front of queue.
56  // TODO: add way to add job after waiting for for empty queue first.
57 
58 private:
59  void _thread_worker(size_t thread_nr);
60 
61  std::mutex _mutex;
62  std::vector<std::thread> _threads;
63  std::deque<Job> _job_queue;
64  size_t _num_unfinished_jobs = 0;
65  std::condition_variable _new_job_cond;
66  std::condition_variable _job_finished_cond;
67 };
68 
69 } // namespace emilib
Definition: thread_pool.hpp:20
void wait()
Wait for all jobs to finish.
ThreadPool()
As many threads as cores, but at least 2.
~ThreadPool()
Will block until all jobs have finished.
void clear()
Remove all jobs in the queue (but those that have already started will still finish).
void add_void(const Job &job)
Add to queue and return immediately.
std::future< Result > add(std::function< Result()> job)
Add to queue and return immediately.
Definition: thread_pool.hpp:45
Definition: coroutine.hpp:18