C++实现一个简易的线程池
文章目录
- 线程池的概念
- 什么是线程池
- 线程池的优点
- 线程池的应用场景
- 线程池的实现
- 实现思路
- 代码实现
线程池的概念
什么是线程池
顾名思义,线程池就是一个有很多空闲线程的池子(线程的数量受到限制),需要用到多执行流进行任务处理时,就从池子中唤醒一个线程去处理任务
线程池的优点
- 避免大量线程频繁创建和销毁带来的时间成本
:如果在一开始即创建好线程,要用的时候直接从线程池中取出,用完再放回,这样就大大减少了创建与销毁带来的时间成本 - 避免无限制的线程创建导致资源耗尽
:线程池限制了线程的数量,这样就保证了不会因为线程创建过多导致资源耗竭,程序崩溃的情况
线程池的应用场景
有大量的数据处理请求,需要多执行流并发/并行处理
线程池的实现
实现思路
首先线程池的核心,就是大量的线程和一个任务缓冲队列。在线程池创建时就提前创建好一定数量的线程,如果有任务到来则将任务放入缓冲队列中,此时唤醒线程池中的线程取出任务进行处理,如果线程池没有空闲线程,则阻塞任务,直到有线程处理完任务回归线程池中。同时,因为不同任务有不同的处理方法,所以要开放接口给外界,处理的数据和方法由外界自己定,线程池只负责调用对应的任务处理方法进行处理,不关心其中的内容。这样就更具有灵活性。
代码实现
下面就来实现一个线程池,具体的细节都有注释
#include<iostream>
#include<pthread.h>
#include<cstdlib>
#include<queue>//类型重命名,将处理的方法定义为一个函数指针
typedef void (*handler_t)(int);const size_t MAX_SIZE = 10;//任务
class ThreadTask
{public://设置需要处理的数据与对应的处理方法void SetTask(int data, handler_t handler){_data = data;_handler = handler;}//处理数据void Run(){_handler(_data);}private:int _data;handler_t _handler;
};//线程池
class ThreadPool
{public:ThreadPool(size_t capacity = MAX_SIZE) : _capacity(capacity){pthread_cond_init(&_cond, NULL);pthread_mutex_init(&_mutex, NULL);//线程池提前创建线程for(size_t i = 0; i < _capacity; i++){pthread_t pid;int ret = pthread_create(&pid, NULL, start_routine, this);if(ret){std::cout << "线程创建失败" << std::endl;exit(-1);}}}~ThreadPool(){pthread_cond_destroy(&_cond);pthread_mutex_destroy(&_mutex);}void Push(ThreadTask& Task){//互斥锁保证线程安全pthread_mutex_lock(&_mutex);//将任务放入队列中_queue.push(Task);pthread_mutex_unlock(&_mutex);//唤醒线程池全部线程,谁抢到谁就来处理这个任务pthread_cond_broadcast(&_cond);}//入口函数的参数只能有一个void*,所以需要写为static函数来去掉隐含的this指针static void* start_routine(void *arg){//将void*强转为需要的类型ThreadPool* pool = (ThreadPool*)arg;while(1){pthread_mutex_lock(&pool->_mutex); //如果任务队列为空则使线程循环等待while(pool->_queue.empty()){pthread_cond_wait(&pool->_cond, &pool->_mutex);}ThreadTask Task;//将任务出队进行处理Task = pool->_queue.front();pool->_queue.pop();pthread_mutex_unlock(&pool->_mutex);//解锁后再处理,因为加锁只是保证队列操作的安全性Task.Run();}return NULL;}private://互斥锁保证线程安全,条件变量保证任务的提交与处理同步pthread_cond_t _cond;pthread_mutex_t _mutex;size_t _capacity;std::queue<ThreadTask> _queue;
};
下面写一个函数来测试一下
#include "ThreadPool.hpp"
#include<unistd.h>void handler1(int data)
{std::cout << "线程ID:"<< pthread_self() <<" 处理奇数数据:" << data << std::endl;sleep(1);
}void handler2(int data)
{std::cout << "线程ID:"<< pthread_self() <<" 处理偶数数据:" << data << std::endl;sleep(1);
}int main()
{ThreadPool pool;for(int i = 0; i < 10; i++){ThreadTask task;//分别处理奇数和偶数if(i & 1){task.SetTask(i, handler1);}else{task.SetTask(i, handler2); }//任务放入队列中pool.Push(task);}//休眠一段时间防止结束后主线程退出sleep(100);return 0;
}
使用两种不同的处理方法来分别处理0-9的奇偶数
运行截图
C++实现一个简易的线程池相关推荐
- 分享:一个简单的线程池的实现
一个简单的线程池的实现 http://my.oschina.net/hejiula/blog/110519
- 高并发编程-自定义简易的线程池(2),体会原理
文章目录 概述 示例 概述 高并发编程-自定义简易的线程池(1),体会原理 中只实现了任务队列,我们这里把其余的几个也补充进来 拒绝策略 关闭线程池 最小 最大 活动线程数 - 示例 比较简单,直接上 ...
- 手写一个简单的线程池MyThreadPool
说明 手写的一个简单的线程池,旨在帮助了解线程池的工作原理. 核心内容 核心工作线程 任务阻塞队列 定义一个内部类去实现核心工作线程 /*** 内部类:工作的核心线程*/private final c ...
- 如何写一个高效进程/线程池_关于高效企业测试的思考(1/6)
如何写一个高效进程/线程池 企业中的测试仍然没有得到应有的广泛应用. 编写尤其是维护测试需要花费时间和精力,但是缩短软件测试并不是解决方案. 为了提高测试效率,应该追求哪些范围,方法和测试技术? 基于 ...
- 一个简单的线程池设计方案
一个简单的线程池本质上是生产者-消费者模型,一般是线程池负责消费任务,任务分配线程负责生产任务,任务可以由队列.链表或全局变量等数据结构承担.如果生产和消费速度差不多,可以采用环形队列结构:如果任务有 ...
- 用Python实现一个简单的线程池
线程池的概念是什么? 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收 ...
- 高并发编程-自定义简易的线程池(1),体会原理
文章目录 概述 示例 概述 我们工作中,并发编程必然离不开jdk提供的j.u.c中的线程池 ,假设让我们自己去设计一个线程池,该从哪几个方面来着手考虑呢? 首先: 既然是线程池 , 那必然 有个初始化 ...
- 程序员修仙之路--设计一个实用的线程池
菜菜呀,我最近研究技术呢,发现线上一个任务程序线程数有点多呀 CEO,CTO,CFO于一身的CXO x总,你学编程呢? 菜菜 作为公司总负责人,我以后还要管理技术部门呢,怎么能不会技术呢 CEO,CT ...
- Linux C 实现一个简单的线程池
https://www.cnblogs.com/GyForever1004/p/9185240.html 线程池的定义 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动 ...
最新文章
- 100万人同时抢1万张火车票,极限并发带来的思考
- MySQL · 引擎特性 · InnoDB 事务子系统介绍
- Java 文件操作-File
- 【Antlr】cannot create implicit token for string literal in non-combined grammar xx
- Ancient Berland Circus CodeForces - 1C
- python3.8安装pyinstaller失败_pip命令安装 pyinstaller失败解决办法
- codevs1068 乌龟棋 题解
- 科学语言与matlab计算 实验2、3
- smb协议讲解_SMB/CIFS协议解析
- 【软件测试】:测试改进措施总结
- SAP基本计量单位更改
- Introduction to Robotics 总结1~6
- Jpress项目学习纪录片(一) -- 环境搭建
- 工行二维码支付时代来了
- 计算机专业高级工程师考哪些专业,高级工程师职称考试项目有哪些
- matlab密度特征,关于用MATLAB应用程序估算风险中性密度的性能分析和介绍
- 高性能计算服务器8280,AMD秀实力:第二代霄龙64核性能是英特尔Xeon Platinum8280两倍...
- WPS表格:数据基本计算与引用-函数与表达式
- PHP日期转换为时间戳
- 新手机为什么一注册陌陌就封解析硬改软改
热门文章
- plsql(轻量版)_触发器
- SpringBoot服务整合(整合邮件服务、定时调度、Actuator监控)
- 闭包案例产生多个相同的随机数 沙箱
- c语言仓库管理系统链表,仓库管理系统 C语言 C++ 数据结构 链表 课程设计
- 【Homework】什么是多态,多态具体体现有哪些?
- python unitest框架_python单元测试框架Unitest
- Cortex-M3-MPU(存储器保护单元)
- 常用LINQ关键字用法汇总
- iPhone X系列 的获取 - 安全区顶部和底部高度
- 阿里RocketMQ是怎样孵化成Apache顶级项目的?