网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
#include "CThreadPool.h"
#include <iostream>
using namespace std;
//void\* start\_routine\_A(void\* arg);
// 核心线程回调函数
void\* start\_routine\_A(void\* arg)
{
CThreadPool\* pool = (CThreadPool\*)arg; //获得本类对象
while (1)
{
//1、 用条件变量阻塞线程(也就是让线程睡眠等待唤醒)
pool->lock\_mutex(); //锁上cond, 保证只能cond被用的情况下不会抢占
cout << pthread\_self() << " is waitting for task..." << endl;
//pool->wait\_for\_wake(pool); //pthread\_cond\_wait()函数被调用,锁会自动解开,返回的时候在被锁上
pool->wait\_for\_wake();
cout << pthread\_self() << " is wake up for task......" << endl;
pool->unlock\_mutex(); //公共条件遍历用完就解开锁,尽可能的缩小锁范围
//2、 线程唤醒后从任务队列内拿任务执行
pool->pick\_task();
cout << "core end." << endl;
}
}
CThreadPool::CThreadPool(int num):initTotalNum(num)
{
//初始化两个锁
pthread\_cond\_init(&this->cond, NULL);
pthread\_mutex\_init(&this->mutex, NULL);
}
void CThreadPool::lock\_mutex()
{
pthread\_mutex\_lock(&this->mutex);
}
void CThreadPool::unlock\_mutex()
{
pthread\_mutex\_unlock(&this->mutex);
}
void CThreadPool::wait\_for\_wake()
{
pthread\_cond\_wait(&this->cond, &this->mutex);
cout << "core Thread is wake up, pid = " << this->pid << endl;
}
void CThreadPool::pick\_task()
{
this->lock\_mutex(); //队列也是公共资源,用之前先上锁
if (!this->task_que.empty())
{
CTask\* t = this->task_que.front(); //从队列拿任务(注意:队列是先进先出,栈是先进后出)
this->task_que.pop(); //拿了就踢出队列
this->unlock\_mutex(); //公共资源用完解锁
t->run();
}
else
{
cout << "wocao?" << endl;
this->unlock\_mutex(); //队列为空就解锁,避免进入死锁
}
}
void CThreadPool::work()
{
// 先创建核心线程
for (int i = 0; i < this->core_num; i++)
{
pthread\_create(&this->pid, NULL, start_routine_A, this);
cout << "The " << i + 1 << " core thread has been created." << endl;
sleep(1);
}
// 初始化当前线程数
this->thread_num = core_num;
}
void CThreadPool::add\_task(CTask\* &task)
{
this->task_que.push(task); //加入任务队列
// 当前任务队列长度 > 核心线程数 && 不超过最大线程数?创建非核心线程 : 保持;
if (task_que.size() > core_num && thread_num <= initTotalNum)
{
this->increa\_thread\_num();
pthread\_create(&this->pid, NULL, start_routine_B, this);
// sleep(1);
pthread\_cond\_signal(&this->cond);
return;
}
pthread\_cond\_signal(&this->cond); //唤醒线程
}
五、关键点
1、pthread_cond_t cond 是线程的公共资源,线程在使用条件变量时需要有上锁和解锁的操作;
2、pthread_cond_wait(); 会在调用的时候自动给mutex解锁,等到返回时会还原锁状态;
六、后续优化方向
1、 设置核心线程数+ 最大线程数 : 开始仅初始化核心线程数的工作线程,在任务量大于核心线程数的情况下再挨个创建非核心线程进行任务处理;
2、 非核心线程超时等待自动销毁: 会应用到pthread_cond_timedwait() ; 其中的超时参数为绝对时间,如果传递错误会出现阻塞失效的情况(也就是仔等待时间内却直接超时返回)
3、 结束标志位的使用: 可以看到我这里虽然声明了结束标志位却没有用到,因为我暂时也不太清楚该用在哪里最合适,所以暂且放着等待下一个优化版本再加上;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
//bbs.csdn.net/topics/618668825)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!