线程池用于创建线程,添加任务后,空闲线程会取出任务并执行
void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; } //设置队列长度 void setThreadInitCallback(const Task& cb) //设置线程初始化回调函数
void run(const Task& f); //执行线程函数
private: bool isFull() const; void runInThread(); Task take(); mutable MutexLock mutex_; //mutable在const函数中表示可以更改,是因为要上锁解锁修改状态 Condition notEmpty_; //有界阻塞队列通用手法 Condition notFull_; string name_; Task threadInitCallback_; boost::ptr_vector<muduo::Thread> threads_; //指针容器,储存指向线程的指针 std::deque<Task> queue_; //任务队列 size_t maxQueueSize_; bool running_; };
void ThreadPool::start(int numThreads) { assert(threads_.empty()); running_ = true; threads_.reserve(numThreads); //预留空间防止重复释放和分配空间 for (int i = 0; i < numThreads; ++i) { char id[32]; snprintf(id, sizeof id, "%d", i+1); threads_.push_back(new muduo::Thread( //通过function和bind的配合传递函数和参数 boost::bind(&ThreadPool::runInThread, this), name_+id)); threads_[i].start(); } if (numThreads == 0 && threadInitCallback_) //如果没有线程同时指定了函数则执行 { threadInitCallback_(); } }
void ThreadPool::stop() { { MutexLockGuard lock(mutex_); //上锁,配合条件变量通知其他线程 running_ = false; notEmpty_.notifyAll(); //通知所有线程执行join } for_each(threads_.begin(), threads_.end(), boost::bind(&muduo::Thread::join, _1)); }
void ThreadPool::run(const Task& task) { if (threads_.empty()) //当前线程执行函数 { task(); } else { MutexLockGuard lock(mutex_); //生产者消费者问题 while (isFull()) { notFull_.wait(); } assert(!isFull()); queue_.push_back(task); notEmpty_.notify(); //只通知一个线程即可 } }
void ThreadPool::runInThread() { try { if (threadInitCallback_) //注册了初始化函数 { threadInitCallback_(); } while (running_) { Task task(take()); //取出任务,进行消费 if (task) { task(); } } }