线程池概念以及代码实现

画图理解

线程池其实也是一种生产者消费者模型。

何为线程池,其实就是在程序运行期间提前申请一批线程在自己的栈中等待任务的到来。

将任务投入到线程池中,在线程池中让其中一个线程完成任务。

 为了让线程池中不让线程闲置着,一般可能会有多个执行流向同一个线程池发送任务,那么就必须需要一个缓冲区来存放任务,提高效率。

 

 提前申请一批线程当消费者,对这批线程进行封装,我们就叫做线程池。

代码:

Thread.hpp,对线程封装代码

#pragma once#include <iostream>
#include <pthread.h>using namespace std;
typedef void*(*func_t)(void*);struct ThreadData
{ThreadData(const std::string&name,void*ages=nullptr):_name(name),_ages(ages){}std::string _name;void* _ages;
};class Thread
{
public:Thread(func_t run_func,std::string name,void*ages):_run_func(run_func),_TData(new ThreadData(name,ages))    {}~Thread(){}void run_thread(){pthread_create(&_tid,nullptr,_run_func,(void*)_TData);}void join_thread(){pthread_join(_tid,nullptr);}private:pthread_t _tid;func_t _run_func;ThreadData*_TData;
};

ThreadPool.hpp:线程池代码

#pragma once
#include "Thread.hpp"
#include <semaphore.h>
#include <vector>
#include <queue>
#include <unistd.h>class auto_lock
{
public:auto_lock(pthread_mutex_t *lock) : _lock(lock){pthread_mutex_lock(_lock);}~auto_lock(){pthread_mutex_unlock(_lock);}private:pthread_mutex_t *_lock;
};template <typename Ty, size_t Num = 3>class ThreadPool
{
private:std::vector<Thread *> *_pool;std::queue<Ty> *_queue_exe;std::queue<Ty> *_queue_st;pthread_mutex_t *_detect_lock;pthread_mutex_t *_pthreads_lock;pthread_cond_t *_cond;pthread_cond_t *_swap_cond;pthread_t *_detect_tid;
public:bool queue_empty(){return _queue_exe->empty();}bool queue_all_empty(){return _queue_exe->empty()&&_queue_st->empty();}void signal_wait(){pthread_cond_wait(_cond, _detect_lock);}void signal_send(){pthread_cond_signal(_cond);}void signal_wait_swap(){pthread_cond_wait(_swap_cond, _pthreads_lock);}void signal_send_swap(){pthread_cond_signal(_swap_cond);}pthread_mutex_t *detect_lock(){return _detect_lock;}pthread_mutex_t *pthreads_lock(){return _pthreads_lock;}Ty get_task(){Ty task;task =_queue_exe->front();_queue_exe->pop();return task;}ThreadPool(): _pool(new std::vector<Thread *>), _detect_lock(new pthread_mutex_t), _pthreads_lock(new pthread_mutex_t), _cond(new pthread_cond_t), _swap_cond(new pthread_cond_t), _queue_exe(new std::queue<Ty>), _queue_st(new std::queue<Ty>), _detect_tid(new pthread_t){pthread_mutex_init(_detect_lock, nullptr);pthread_mutex_init(_pthreads_lock, nullptr);pthread_cond_init(_swap_cond, nullptr);pthread_cond_init(_cond, nullptr);for (int i = 0; i < Num; ++i){std::string name = "thread_";name += std::to_string(i + 1);_pool->push_back(new Thread(TRFunc, name, (void *)this));}}~ThreadPool(){pthread_mutex_destroy(_detect_lock);pthread_mutex_destroy(_pthreads_lock);pthread_cond_destroy(_swap_cond);pthread_cond_destroy(_cond);for (int i = 0; i < Num; ++i){_pool->at(i)->join_thread();}}void RunAllThread(){for (int i = 0; i < Num; ++i){std::cout << "线程启动!!" << std::endl;_pool->at(i)->run_thread();}pthread_create(_detect_tid,nullptr,detect,this);cout<<"Start the reconnaissance thread"<<endl;}static void *TRFunc(void *ages){ThreadData *TData = (ThreadData *)ages;ThreadPool<Ty> *TPool = (ThreadPool<Ty> *)TData->_ages;while (1){sleep(1);Ty task;{//cout<<"debug 1"<<endl;auto_lock lock(TPool->pthreads_lock());// cout<<"debug 2"<<endl;while (TPool->queue_empty()){//cout<<"debug 3"<<endl;TPool->signal_wait_swap();//cout<<"debug 4"<<endl;}//cout<<"debug 5"<<endl;task=TPool->get_task();//cout<<"debug 6"<<endl;}task();}}void push_task(const Ty &task){ auto_lock lock(detect_lock());_queue_st->push(task);signal_send();}static void*detect(void*ags){ThreadPool<Ty> *TPool = (ThreadPool<Ty> *)ags;while(1){if(TPool->queue_empty())//不会放数据到exe队列中,为空的时候是一定为空的,不会改变的。{auto_lock lock(TPool->detect_lock());if(TPool->queue_all_empty()){TPool->signal_wait();}TPool->swap();cout<<"debug swap~~~~~~~~~~~"<<endl;TPool->signal_send_swap();}}}void swap(){std::swap(_queue_exe,_queue_st);}void size(){cout<<"_queue_exe size:"<<_queue_exe->size()<<" ";printf("%p ",_queue_exe);cout<<"_queue_st size:"<<_queue_st->size();printf("%p \n",_queue_st);}};

主函数代码:单生产者

#include "ThreadPool.hpp"
#include <functional>
#include <memory>
class Task
{
public:typedef std::function<int(int,int)> func_t;Task(){}Task(int x,int y,func_t func):_x(x),_y(y),_func(func){}void operator ()(){std::cout<<"thread id:"<<pthread_self()<<" ";std::cout<<_x<<"+"<<_y<<"="<< _func(_x,_y)<<std::endl;}
private:int _x;int _y;Task::func_t _func;
};int main()
{using namespace std;ThreadPool<Task,1> p;p.RunAllThread();int cnt=0;while(1){int x=rand()%20;int y=rand()%30;Task task(x,y,[](int x,int y)->int { return x+y;});p.size();p.push_task(task);if(cnt++%3==0){sleep(1);}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/87559.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验表明:人工智能生成的论文可在全美大多数大学的文社科类课程中获得及格成绩

两门A&#xff0c;一门A-&#xff0c;一门B&#xff0c;一门B-&#xff0c;一门及格。 对于一名哈佛大学的大一新生来说&#xff0c;这已经是一份相当不错的成绩单&#xff0c;合计3.57的GPA成绩也很可观。 Maya Bodnick 在哈佛大学的政治专业就读大一&#xff0c;上面提到的…

震动分析国标GB/T 19873.3-2019/ISO 13373-3:2015笔记

1.国家标准 1.1震动测量 现行国家标准是&#xff1a;GB/T 19873.2-2009 机器状态监测与诊断 振动状态监测 第2部分&#xff1a;振动数据处理、分析与描述 它的起草人&#xff1a; 郑州机械研究所。西安热工研究院有限公司。东南大学。 主要起草人 韩国明 、张学延 、傅行…

八路参考文献:[八一新书]许少辉.乡村振兴战略下传统村落文化旅游设计[M]北京:中国建筑工业出版社,2022.

八路参考文献&#xff1a;&#xff3b;八一新书&#xff3d;许少辉&#xff0e;乡村振兴战略下传统村落文化旅游设计&#xff3b;&#xff2d;&#xff3d;北京&#xff1a;中国建筑工业出版社&#xff0c;&#xff12;&#xff10;&#xff12;&#xff12;&#xff0e;

精进面试技巧:如何在程序员面试中脱颖而出

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

论文阅读_模型结构_LoRA

name_en: LoRA: Low-Rank Adaptation of Large Language Models name_ch: LORA&#xff1a;大语言模型的低阶自适应 paper_addr: http://arxiv.org/abs/2106.09685 date_read: 2023-08-17 date_publish: 2021-10-16 tags: [‘深度学习’,‘大模型’] author: Edward J. Hu cita…

利用深度蛋白质序列嵌入方法通过 Siamese neural network 对 virus-host PPIs 进行精准预测【Patterns,2022】

研究背景&#xff1a; 病毒感染可以导致多种组织特异性损伤&#xff0c;所以 virus-host PPIs 的预测有助于新的治疗方法的研究&#xff1b;目前已有的一些 virus-host PPIs 鉴定或预测方法效果有限&#xff08;传统实验方法费时费力、计算方法要么基于蛋白结构或基因&#xff…

深眸科技创新赋能视觉应用产品,以AI+机器视觉解决行业应用难题

随着工业4.0时代的加速到来&#xff0c;我国工业领域对于机器视觉技术引导的工业自动化和智能化需求持续上涨&#xff0c;国内机器视觉行业进入快速发展黄金期&#xff0c;但需求广泛出现同时也对机器视觉产品的检测能力提出了更高的要求。 传统机器视觉由人工分析图像特征&am…

TCP协议的重点知识点

TCP协议的重点知识点 TCP(传输控制协议)是一种面向连接、可靠的数据传输协议,工作在传输层,提供可靠的字节流服务。它是互联网协议栈中最重要、最复杂的协议之一,也是面试中常被问到的知识点。本文将详细介绍TCP协议的各个重要概念。 TCP基本特性 TCP主要具有以下基本特性: …

XML—DTD、 Schema

目录 DTD是什么&#xff1f; DTD有什么用途&#xff1f; DTD与XML有什么联系&#xff1f; DTD原理图 外部DTD DTD文件book.dtd: 使用外部DTD文件的XML文件 PCDATA XML 文档构建模块 一、元素 1、元素声明 ①、有元素&#xff1a; ②、空元素&#xff1a; ③、ANY…

JVM 判定对象是否死亡的两种方式

引用计数法&#xff1a;&#xff08;脑门刻字法&#xff09;和 可达性分析 引用计数算法 引用计数器的算法是这样的&#xff1a;在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一…

Linux 桌面上的 Firefox 面临着大问题

导读毫无疑问&#xff0c;无论是在桌面、笔记本电脑还是移动设备上&#xff0c;浏览器都是任何操作系统中最重要的应用之一。 如果没有一个功能强大、快速且稳定的浏览器&#xff0c;操作系统的实用性将大幅度降低&#xff0c;以至于我相当确定&#xff0c;如果一个操作系统没有…

将Spring boot 项目部署到tomcat服务艰难

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z X Y Z