From $ROOTSYS/tutorials/thread/threadPool.C

// Usage:
// root [0] .L threadPool.C++
// root [1] threadPool(10)  10 = numThreads

// STD
#include <iostream>
#include <iterator>
#include <vector>
#ifndef _WIN32
#include <unistd.h>
#endif
// ThreadPool
#include "TThreadPool.h"
// ROOT
#include "TThread.h"

//=============================================================================
using namespace std;
//=============================================================================
const size_t g_sleeptime = 1; // in secs.
const size_t g_multTasks = 50;
//=============================================================================

// define a custom parameters type for task objects
enum EProc {start, clean};

// a class defining task objects
class TTestTask: public TThreadPoolTaskImp<TTestTask, EProc>
{
public:
   bool runTask(EProc /*_param*/) {
      m_tid = TThread::SelfId();
      TThread::Sleep(g_sleeptime, 0L);
      return true;
   }
   unsigned long threadID() const {
      return m_tid;
   }

private:
   unsigned long m_tid;
};

//=============================================================================
void threadPool(size_t _numThreads = 10, bool _needDbg = false)
{
   cout << "ThreadPool: starting..." << endl;
   // number of tasks to process
   size_t numTasks(_numThreads * g_multTasks);

   // create a thread pool object
   // _numThreads - a number of threads in the pool
   // _needDbg - defines whether to show debug messages
   TThreadPool<TTestTask, EProc> threadPool(_numThreads, _needDbg);

   // create a container of tasks
   vector <TTestTask> tasksList(numTasks);

   cout << "ThreadPool: getting tasks..." << endl;
   cout << "ThreadPool: processing tasks..." << endl;
   // push tasks to the ThreadPool
   // tasks can be also pushed asynchronously
   for (size_t i = 0; i < numTasks; ++i) {
      threadPool.PushTask(tasksList[i], start);
   }

   // Stop thread pool.
   // The parameter "true" requests the calling thread to wait,
   // until the thread pool task queue is drained.
   threadPool.Stop(true);
   cout << "ThreadPool: done" << endl;
}

 threadPool.C:1
 threadPool.C:2
 threadPool.C:3
 threadPool.C:4
 threadPool.C:5
 threadPool.C:6
 threadPool.C:7
 threadPool.C:8
 threadPool.C:9
 threadPool.C:10
 threadPool.C:11
 threadPool.C:12
 threadPool.C:13
 threadPool.C:14
 threadPool.C:15
 threadPool.C:16
 threadPool.C:17
 threadPool.C:18
 threadPool.C:19
 threadPool.C:20
 threadPool.C:21
 threadPool.C:22
 threadPool.C:23
 threadPool.C:24
 threadPool.C:25
 threadPool.C:26
 threadPool.C:27
 threadPool.C:28
 threadPool.C:29
 threadPool.C:30
 threadPool.C:31
 threadPool.C:32
 threadPool.C:33
 threadPool.C:34
 threadPool.C:35
 threadPool.C:36
 threadPool.C:37
 threadPool.C:38
 threadPool.C:39
 threadPool.C:40
 threadPool.C:41
 threadPool.C:42
 threadPool.C:43
 threadPool.C:44
 threadPool.C:45
 threadPool.C:46
 threadPool.C:47
 threadPool.C:48
 threadPool.C:49
 threadPool.C:50
 threadPool.C:51
 threadPool.C:52
 threadPool.C:53
 threadPool.C:54
 threadPool.C:55
 threadPool.C:56
 threadPool.C:57
 threadPool.C:58
 threadPool.C:59
 threadPool.C:60
 threadPool.C:61
 threadPool.C:62
 threadPool.C:63
 threadPool.C:64
 threadPool.C:65
 threadPool.C:66
 threadPool.C:67
 threadPool.C:68
 threadPool.C:69
 threadPool.C:70
 threadPool.C:71
 threadPool.C:72
 threadPool.C:73
 threadPool.C:74