设计线程池
大纲
成员变量

成员函数

先完成一个基本框架的设计
构造
由于我们调用是说我们自己设计的thread


start wait stop
和单线程那里类似
主要是让所有线程都开启上面那些函数

测试一下


以上基本功能已经实现,接下来我们对其进行改变一下
这个任务相当于是全局的,要是我们想要让他在类里面实现该又怎么做呢??

我们将任务函数变成成员函数


编译的时候发现失败了这是为什么????


普通成员函数隐含参数this,类型是 void (ThreadPool<int>::*)(),不是普通函数指针 void (*)(),Thread 类构造只接收普通函数指针,编译直接报错。
那么应该如何解决???
首先我们可以先让他变成static


当然我们也可以用
直接用lambda 捕获 this传入,完美解决!
std::function<void()>可以接收:

上面谈完这个问题,
接下来我们对任务进行更加细致的修改
再执行任务的时候是要进行加锁和减锁的
因为要求每个线程调用的任务是不重复的

再临界区内我们哟啊检测任务,
如果有任务该怎么办
没有任务有该怎么办

有任务,取任务就是将公共资源变成私有的

enqueue

唤醒线程的逻辑是只要有有线程处于休眠状态就进行唤醒
测试



对于stop逻辑的更新
需求:
也就是说对于handler函数那里还需要做出调整
当任务不为空的时候,要继续执行,也就是说不能让线程休眠
当线程池要退出时,线程也不能休眠,
任意满足上面两条都是不可以进行休眠
—>那什么时候可以进行休眠呢??
当上面两条都不满足的时候


测试
class Task
{
public:
~Task()
{
}
Task(int x, int y)
: _x(x),
_y(y)
{
}
void Excute()
{
_ret = _x + _y;
}
void operator()()
{
_ret = _x + _y;
}
string PrintAns()
{
return to_string(_x) + "+" + to_string(_y) + "=" + to_string(_ret);
}
string PrintQuestion()
{
return to_string(_x) + "+" + to_string(_y) + "=?";
}
private:
int _x;
int _y;
int _ret;
};
using task_t = function<void()>;
int main()
{
srand(time(nullptr) ^ getpid());
ENABLE_CONSOLESTRATEGY();
unique_ptr<ThreadPool<Task>> pool = make_unique<ThreadPool<Task>>();
pool->Start();
int cnt = 10;
while (cnt–)
{
int x = rand() % 10 + 1;
int y = rand() % 20 + 1;
Task t(x, y);
sleep(1);
pool->Enqueue(t);
sleep(1);
}
pool->Wait();
return 0;
}
void handlertask()
{
char buf[64];
pthread_getname_np(pthread_self(), buf, sizeof(buf));
while (1)
{
// 保护临界区
_mutex.Lock();
// 检测任务. 不休眠->1.队列不为空2.线程池退出
while (_qu_task.empty()&&_isrunning)
{
// 没有任务
_slaver_sleep_count++;
_cond.Wait(_mutex);
_slaver_sleep_count–;
}
// 有任务或者线程池退出
// 1&&2 —->break
if(!_isrunning&&_qu_task.empty())
{
_mutex.Unlock();
break;
}
// 如果模板是一个类要怎么做
T mytask = _qu_task.front();
_qu_task.pop();
// 处理任务??需要在临界区内执行吗???
// 不需要不然就成为单线程
_mutex.Unlock();
LOG(LogLevel::INFO) << "my name:" << buf;
mytask();
LOG(LogLevel::INFO) << "my job:" <<mytask.PrintAns();
}
}

网硕互联帮助中心



评论前必须登录!
注册