Thread Pools and Work Queues
One reported question asks for a thread pool with mutexes, semaphores, threads and a queue, and several other firms probe the same ground. It is a good exercise because the naive version is twenty lines and every interesting question is about what the naive version does wrong. This lesson writes the whole class, then walks through each of those questions with the code in front of you.
The whole class
A pool is a fixed set of worker threads and a queue of tasks. Each worker loops: take a task, run it, repeat. Here is all of it, using the condition variable discipline from three lessons ago.
class ThreadPool {
public:
explicit ThreadPool(std::size_t n) {
workers_.reserve(n);
for (std::size_t i = 0; i < n; ++i)
workers_.emplace_back([this] { worker(); });
}
~ThreadPool() {
{
std::lock_guard lock(m_);
stopping_ = true;
}
cv_.notify_all();
for (auto& t : workers_) t.join();
}
template <class F>
auto submit(F f) -> std::future<decltype(f())>; // below
private:
void worker() {
for (;;) {
std::function<void()> task;
{
std::unique_lock lock(m_);
cv_.wait(lock, [this] { return stopping_ || !tasks_.empty(); });
if (stopping_ && tasks_.empty()) return;
task = std::move(tasks_.front());
tasks_.pop_front();
}
task(); // outside the lock, deliberately
}
}
std::mutex m_;
std::condition_variable cv_;
std::deque<std::function<void()>> tasks_;
std::vector<std::thread> workers_;
bool stopping_ = false;
};
The rest of this lesson is for subscribers
Unlock every lesson in Systems Programming for Trading, and every other premium course.
Subscribe to continueTest your knowledge
Keep reading Systems Programming for Trading
27 lessons in this course, and every other premium course, on one subscription.
- Every lesson in every course, with the worked examples and interactive simulators
- Graded questions on every lesson, with explanations for the wrong answers as well as the right one
- The trainers, timed assessments and brainteaser library that go with them