线程池用于创建线程,添加任务后,空闲线程会取出任务并执行
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();
}
}
}