news 2026/9/10 23:36:59

Linux之线程池(二)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux之线程池(二)

设计线程池

大纲

成员变量

成员函数

先完成一个基本框架的设计

构造

由于我们调用是说我们自己设计的thread

start wait stop

和单线程那里类似

主要是让所有线程都开启上面那些函数

测试一下

以上基本功能已经实现,接下来我们对其进行改变一下

这个任务相当于是全局的,要是我们想要让他在类里面实现该又怎么做呢??

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

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

普通成员函数隐含参数this,类型是void (ThreadPool<int>::*)()不是普通函数指针void (*)(),Thread 类构造只接收普通函数指针,编译直接报错。

那么应该如何解决???

首先我们可以先让他变成static

当然我们也可以用

直接用lambda 捕获 this传入,完美解决!

std::function<void()>可以接收:

  1. 普通全局函数
  2. lambda 表达式(可以捕获this
  3. bind 绑定成员函数

上面谈完这个问题,

接下来我们对任务进行更加细致的修改

再执行任务的时候是要进行加锁和减锁的

因为要求每个线程调用的任务是不重复的

再临界区内我们哟啊检测任务,

如果有任务该怎么办

没有任务有该怎么办

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

enqueue

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

测试

对于stop逻辑的更新

需求:

  1. 使用_isrunning标志位控制线程池运行状态
  2. 队列中剩余任务全部执行完毕之后,工作线程才允许退出
  3. 使用Broadcast唤醒所有休眠的工作线程
  4. 线程处理函数(handler)内部判断条件,自动 break 退出循环

也就是说对于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(); } }

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 16:37:21

大一新生学 C 语言:先动手,再学基础语法

学习东西不能光听&#xff0c;一定要多动手&#xff0c;多实践&#xff0c;才能看出问题&#xff0c;并且去解决。往往你听起来会了&#xff0c;但是实际让你在敲一遍刚刚的代码&#xff0c;真不一定能敲对。学习编程尤其如此。看视频、听讲解&#xff0c;感觉每一步都懂了&…

作者头像 李华
网站建设 2026/8/30 12:46:43

Barrick海杂波模型Matlab实战:从物理原理到工程部署

1. 这不是教科书里的公式推导&#xff0c;而是一次实打实的海面雷达回波建模实战 “一种雷达海杂波反射率经验模型matlab模拟仿真”——看到这个标题&#xff0c;你脑子里浮现的是不是一堆希腊字母、积分符号和“参考文献[3]”&#xff1f;别急。我干这行十二年&#xff0c;从岸…

作者头像 李华
网站建设 2026/8/30 9:44:37

用触摸屏自制便携功率分析仪:波形显示与功率测量一体化设计

项目概述与核心设计思路功率分析仪&#xff08;Power Analyzer&#xff09;一直是电子工程师和硬件调试人员桌上不可或缺的工具&#xff0c;但市面上的商用功率分析仪价格动辄几千上万&#xff0c;而且操作界面老旧、交互逻辑复杂。这个项目要做的事情很明确&#xff1a;用一块…

作者头像 李华
网站建设 2026/8/30 5:45:37

2026怀化工程建筑材料检测排名 TOP5 CMA 资质提供钢材检测、水泥检测、砂石检测 全覆盖联系方式推荐

怀化城区建材检测机构星罗棋布&#xff0c;既有扎根多年的本土老牌实验室&#xff0c;也有全国连锁的第三方检测平台。建筑总包单位、建材生产厂家、市政工程项目、装修建设企业选材验收时&#xff0c;稍有不慎就会遇上无资质机构出具的检测报告&#xff0c;这类报告根本无法用…

作者头像 李华
网站建设 2026/9/2 2:19:34

手机号查QQ号3分钟快速指南:phone2qq 三步跑通完整教程

手机号查QQ号3分钟快速指南&#xff1a;phone2qq 三步跑通完整教程 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 帮家人找回QQ号&#xff0c;他只记得绑定的手机号&#xff0c;QQ号死活想不起来。用开源小工具 phone2qq 做手机号查…

作者头像 李华