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.

The core

A pool is a fixed set of worker threads and a queue of tasks. Each worker loops: take a task, run it, repeat.

void ThreadPool::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
    }
}

Two decisions in that loop are worth defending out loud.

The task runs outside the lock. Holding the mutex while executing a task serialises the entire pool, which is the single most common mistake in a first implementation and turns a pool into an expensive single thread.

The rest of this lesson is for subscribers

Unlock every lesson in Systems Programming for Trading, and every other premium course.

Subscribe to continue

Test your knowledge

Questions are only available to subscribers.

Keep reading Systems Programming for Trading

19 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