openGPMP
Open Source Mathematics Package
Public Member Functions | Private Attributes | List of all members
gpmp::core::ThreadPool Class Reference

#include <threads.hpp>

Public Member Functions

 ThreadPool ()
 Default constructor that creates a ThreadPool with the number of threads. More...
 
 ThreadPool (int numThreads)
 Constructs a ThreadPool with a given number of worker threads to dispatch functions. More...
 
template<class F , class... Args>
auto enqueue (F &&f, Args &&...args) -> std::future< typename std::invoke_result< F, Args... >::type >
 Enqueues a task to the thread pool. More...
 
 ~ThreadPool ()
 

Private Attributes

std::vector< std::thread > workers
 
std::queue< std::function< void()> > tasks
 
std::mutex queue_mutex
 
std::condition_variable condition
 
bool stop
 

Detailed Description

Examples
factors.cpp, and primes.cpp.

Definition at line 60 of file threads.hpp.

Constructor & Destructor Documentation

◆ ThreadPool() [1/2]

gpmp::core::ThreadPool::ThreadPool ( )
inline

Default constructor that creates a ThreadPool with the number of threads.

Definition at line 78 of file threads.hpp.

78  : ThreadPool(std::thread::hardware_concurrency()) {
79  }
ThreadPool()
Default constructor that creates a ThreadPool with the number of threads.
Definition: threads.hpp:78

◆ ThreadPool() [2/2]

gpmp::core::ThreadPool::ThreadPool ( int  numThreads)
inlineexplicit

Constructs a ThreadPool with a given number of worker threads to dispatch functions.

Parameters
numThreadsThe number of worker threads to be created.

Constructs a ThreadPool object with the specified number of worker threads.

Definition at line 88 of file threads.hpp.

88  : stop(false) {
89 
90  // traverse through the number of threads specified
91  for (int i = 0; i < numThreads; ++i) {
92  // add a new thread to the vector storing workers using lambda
93  // function
94  workers.emplace_back([this] {
95  for (;;) {
96  // worker thread creates task object that holds next task to
97  // be executed
98  std::function<void()> task_obj;
99 
100  // this "symbolizes" the critical section of the TheadPool
101  // class
102  {
103  // worker thread locks queue_mutex
104  std::unique_lock<std::mutex> lock(this->queue_mutex);
105  // wait on conditional_variable (ThreadPool stop OR
106  // queued task), wait() locks/unlocks based on condition
107  // result
108  this->condition.wait(lock, [this] {
109  return this->stop || !this->tasks.empty();
110  });
111  // based on stop OR awaiting tasks, return from the
112  // thread
113  if (this->stop && this->tasks.empty()) {
114  return;
115  }
116 
117  // if above isnt met, move first task in TASKS queue to
118  // the task object to transfer ownership
119  task_obj = std::move(this->tasks.front());
120 
121  // pop the handed off task to make room for a new one.
122  // only ONE thread should remove a task from the queue
123  // at a time
124  this->tasks.pop();
125  }
126 
127  // EXECUTE THE HANDED OFF TASK
128  task_obj();
129  }
130  });
131  }
132  }
std::condition_variable condition
Definition: threads.hpp:69
std::vector< std::thread > workers
Definition: threads.hpp:63
std::mutex queue_mutex
Definition: threads.hpp:67
std::queue< std::function< void()> > tasks
Definition: threads.hpp:65

References workers.

◆ ~ThreadPool()

gpmp::core::ThreadPool::~ThreadPool ( )
inline

Definition at line 185 of file threads.hpp.

185  {
186  {
187  // lock queue_mutex & set stop to true
188  std::unique_lock<std::mutex> lock(queue_mutex);
189  stop = true;
190  }
191  // unblock all threads
192  condition.notify_all();
193  // treaverse threads and join
194  for (std::thread &worker : workers) {
195  worker.join();
196  }
197  }

References condition, queue_mutex, stop, and workers.

Member Function Documentation

◆ enqueue()

template<class F , class... Args>
auto gpmp::core::ThreadPool::enqueue ( F &&  f,
Args &&...  args 
) -> std::future<typename std::invoke_result<F, Args...>::type>
inline

Enqueues a task to the thread pool.

Template Parameters
FType of the function to be enqueued.
ArgsVariadic template parameter pack of the arguments passed to the function.
Parameters
fFunction to be enqueued.
argsArguments passed to the function
Returns
std::future<typename std::result_of<F(Args...)>::type> A future object that will contain the result of the function execution.
Exceptions
std::runtime_errorIf the ThreadPool has already been stopped.
Examples
primes.cpp.

Definition at line 148 of file threads.hpp.

150  {
151 
152  // this is the return type of the passed in function
153  // using return_type = typename std::result_of<F(Args...)>::type;
154  using return_type = typename std::invoke_result<F, Args...>::type;
155 
156  // * SHARED POINTER to PACKAGED TASK used to store the passed in i
157  // function + its arguments
158  // * std::bind used to create function object binded to the
159  // function `f` + its args to the packaged tasks
160  // * std::forward used for forwarding an argument to another
161  // function
162  auto task = std::make_shared<std::packaged_task<return_type()>>(
163  std::bind(std::forward<F>(f), std::forward<Args>(args)...));
164 
165  // the FUTURE obj retrieves the return value of the function passed in
166  std::future<return_type> res = task->get_future();
167  {
168  // aquire lock on queue_mutex for synchronization
169  std::unique_lock<std::mutex> lock(queue_mutex);
170  // check if threadpool stop is initiated
171  if (stop) {
172  throw std::runtime_error("enqueue on stopped ThreadPool");
173  }
174  // add a task using emplace to the queue as a lambda that calls the
175  // packaged task
176  tasks.emplace([task]() { (*task)(); });
177  } // once this is hit, unique_lock is out of scope & mutex is
178  // automatically unlocked
179  // notify one waiting thread of one new task added to the queue
180  condition.notify_one();
181  // the return is the future object
182  return res;
183  }

References condition, queue_mutex, python.linalg::res, stop, and tasks.

Referenced by testing_miller_thread().

Member Data Documentation

◆ condition

std::condition_variable gpmp::core::ThreadPool::condition
private

Definition at line 69 of file threads.hpp.

Referenced by enqueue(), and ~ThreadPool().

◆ queue_mutex

std::mutex gpmp::core::ThreadPool::queue_mutex
private

Definition at line 67 of file threads.hpp.

Referenced by enqueue(), and ~ThreadPool().

◆ stop

bool gpmp::core::ThreadPool::stop
private

Definition at line 71 of file threads.hpp.

Referenced by enqueue(), and ~ThreadPool().

◆ tasks

std::queue<std::function<void()> > gpmp::core::ThreadPool::tasks
private

Definition at line 65 of file threads.hpp.

Referenced by enqueue().

◆ workers

std::vector<std::thread> gpmp::core::ThreadPool::workers
private

Definition at line 63 of file threads.hpp.

Referenced by ThreadPool(), and ~ThreadPool().


The documentation for this class was generated from the following file: