The thread pool is used to create threads. After adding tasks, the idle threads will take out the tasks and execute them.
void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; } //Set the queue length void setThreadInitCallback(const Task& cb) //Set the thread initialization callback function
void run(const Task& f); //Execute thread function
private: bool isFull() const; void runInThread(); Task take(); mutable MutexLock mutex_; //mutable means that it can be changed in the const function, because it is necessary to lock and unlock the modified state Condition notEmpty_; //General method of bounded blocking queue Condition notFull_; string name_; Task threadInitCallback_; boost::ptr_vector<muduo::Thread> threads_; //pointer container, storing pointers to threads std::deque<Task> queue_; //task queue size_t maxQueueSize_; bool running_; };
void ThreadPool::start(int numThreads) { assert(threads_.empty()); running_ = true; threads_.reserve(numThreads); //Reserve space to prevent repeated release and allocation of space for (int i = 0; i < numThreads; ++i) { char id[32]; snprintf(id, sizeof id, "%d", i+1); threads_.push_back(new muduo::Thread( //Pass functions and parameters through the cooperation of function and bind boost::bind(&ThreadPool::runInThread, this), name_+id)); threads_[i].start(); } if (numThreads == 0 && threadInitCallback_) //execute if no thread specifies the function at the same time { threadInitCallback_(); } }
void ThreadPool::stop() { { MutexLockGuard lock(mutex_); //Lock, notify other threads with condition variables running_ = false; notEmpty_.notifyAll(); //Notify all threads to execute join } for_each(threads_.begin(), threads_.end(), boost::bind(&muduo::Thread::join, _1)); }
void ThreadPool::run(const Task& task) { if (threads_.empty()) //The current thread executes the function { task(); } else { MutexLockGuard lock(mutex_); //Producer consumer problem while (isFull()) { notFull_.wait(); } assert(!isFull()); queue_.push_back(task); notEmpty_.notify(); //Only notify one thread } }
void ThreadPool::runInThread() { try { if (threadInitCallback_) //The initialization function is registered { threadInitCallback_(); } while (running_) { Task task(take()); //Take out the task and consume it if (task) { task(); } } }