c++实现简单线程池代码

目录

  • 完整代码
    • TaskPool.cpp
    • TaskPool.h
    • main.cpp

完整代码

TaskPool.cpp

//
// Created by LENOVO on 2021/10/25.
//#include "TaskPool.h"
#include <functional>std::mutex printMutex;TaskPool::TaskPool() : m_bRunning(false)
{}TaskPool::~TaskPool()
{removeAllTasks();
}void TaskPool::init(int threadNum/*= 5*/)
{if (threadNum <= 0)threadNum = 5;m_bRunning = true;for (int i = 0; i < threadNum; i++) {std::shared_ptr<std::thread> spThread;// 这个bind含义是啥spThread.reset(new std::thread(std::bind(&TaskPool::threadFunc, this)));{std::lock_guard<std::mutex> guard(printMutex);std::cout << "Init a thread, id: "<< spThread->get_id() << std::endl;}m_threads.push_back(spThread);}
}void TaskPool::stop()
{m_bRunning = false;// 通知所有线程,不运行了m_cv.notify_all();// 等待所有线程退出for (auto& it : m_threads) {if (it->joinable())it->join();}
}void TaskPool::addTask(Task *task)
{std::shared_ptr<Task> spTask;spTask.reset(task);{// 将task加入队列是互斥的std::lock_guard<std::mutex> guard(m_mutexList);m_taskList.push_back(spTask);}{std::lock_guard<std::mutex> guard(printMutex);std::cout << "add a Task, id: " << spTask->getID() << ", thread id is: " << std::this_thread::get_id() << std::endl;}// 通知一个线程的threadFuncm_cv.notify_one();
}void TaskPool::removeAllTasks()
{{// 需要先互斥地将指向taskList的ptr重置,然后将整个taskList资源cleadstd::lock_guard<std::mutex> guard(m_mutexList);for (auto& it : m_taskList) {it.reset();}m_taskList.clear();}
}void TaskPool::threadFunc()
{std::shared_ptr<Task> spTask;while (true) {// 获取task的过程是互斥的{ // 减少锁的粒度std::unique_lock<std::mutex> guard(m_mutexList);// 如果任务队列为空,那么就一直wait,等待线程被唤醒加入到队列中while (m_taskList.empty()) {if (!m_bRunning)break;// 如果获得了互斥锁,但是条件不满足// wait()会释放锁,挂起当前线程// 条件变量发生变化的时候,wait()将环型挂起的线程并获得锁m_cv.wait(guard);}if (!m_bRunning)break;// 获取队头taskspTask = m_taskList.front();m_taskList.pop_front();}// 如果队列为空,则重新进行尝试获取if (spTask == NULL)continue;// 否则,执行task任务spTask->doIt();// 完成之后,将指针重置spTask.reset();}std::lock_guard<std::mutex> guard(printMutex);std::cout << "exit thread , threadID:" << std::this_thread::get_id() << std::endl;
}

TaskPool.h

//
// Created by LENOVO on 2021/10/25.
//#ifndef UNTITLED_TASKPOOL_H
#define UNTITLED_TASKPOOL_H#include<thread>
#include<mutex>
#include<condition_variable>
#include<list>
#include<vector>
#include<memory>
#include<iostream>extern std::mutex printMutex;class Task{
private:unsigned int id;
public:Task(unsigned int ID){id = ID;}virtual void doIt(){std::lock_guard<std::mutex> guard(printMutex);std::cout << "handle a task ,TaskID is: "<< id << ", thradID is:" << std::this_thread::get_id() << std::endl;}virtual ~Task(){std::lock_guard<std::mutex> guard(printMutex);std::cout << "a task destructed , TaskID is: "<< id << ", thradID is:" << std::this_thread::get_id() << std::endl;}unsigned int getID(){return id;}
};class TaskPool final{
public:TaskPool();~TaskPool();TaskPool(const TaskPool& rhs) = delete;TaskPool& operator=(const TaskPool& rhs) = delete;public:// 初始化线程void init(int threadNum = 5);// 通知所有线程结束运行,并等待所有线程运行结束void stop();void addTask(Task* task);void removeAllTasks();private:void threadFunc();private:std::list<std::shared_ptr<Task>>            m_taskList;std::mutex                                  m_mutexList;std::condition_variable                     m_cv;bool                                        m_bRunning;std::vector<std::shared_ptr<std::thread>>   m_threads;
};#endif //UNTITLED_TASKPOOL_H

main.cpp

#include<chrono>
#include "TaskPool.h"int main()
{TaskPool threadPool;threadPool.init();Task* task = NULL;for (int i = 0; i < 10; i++) {task = new Task(i);threadPool.addTask(task);}std::this_thread::sleep_for(std::chrono::seconds(5));threadPool.stop();return 0;
}

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

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

相关文章

Android静态图片人脸识别的完整demo(附完整源码)

Demo功能&#xff1a;利用android自带的人脸识别进行识别&#xff0c;标记出眼睛和人脸位置。点击按键后进行人脸识别&#xff0c;完毕后显示到imageview上。 第一部分&#xff1a;布局文件activity_main.xml [html] view plaincopyprint?<RelativeLayout xmlns:android&qu…

图论:最短路径搜索--Dijkstra算法(c代码实现)

最近因为辞职&#xff0c;有不少闲功夫&#xff0c;重温下数据结构&#xff0c;顺便练练手。今天说说最短路径搜索算法中的Dijkstra原理和实现。 一&#xff1a;简介 这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点&#xff0c;求图中其它节点到此源节点的…

C++多线程快速入门(五)简单线程池设计

目录设计思路主线程运行逻辑task以及taskpool设计详细流程讲解完整代码打印结果往期回顾设计思路 线程池实际上就是一组线程&#xff0c;当我们需要异步执行一些任务时&#xff0c;经常要通过OS频繁创建和销毁线程&#xff0c;不如直接创建一组在程序生命周期内不会退出的线程…

C--函数

函数:具有特定功能的代码段,分为库函数,自定义函数. 函数定义: 函数返回值类型 函数名(形式参数列表) { 代码段; return 返回值; } 注意:每个函数返回值最多只有一个.return是一个函数结束的标志. 形式参数(形参):函数定义时使用的虚拟参数名,用以接收函数调用是传递过来的实际…

公式系统 - TradeBlazer公式基础 - Bar数据

Bar数据 在介绍Bar数据之前&#xff0c;首先&#xff0c;我们需要讨论一下TradeBlazer公式的计算方法&#xff0c;针对上面介绍的各种公式类型&#xff0c;包含公式应用&#xff0c;在公式进行计算时&#xff0c;都是建立在基本数据源(Bar数据)之上&#xff0c;我们这里所谓的B…

C++网络编程快速入门(一):TCP网络通信基本流程以及基础函数使用

目录流程概述服务器端代码实现客户端代码实现函数和结构讲解sockaddr_in和sockaddrsocket &#xff1a; 创建一个socket连接bind &#xff1a;绑定地址以及端口号问题流程概述 客户端与服务器之间的网络通信基本原理如下所示&#xff0c;复杂一点的架构可能会添加消息中间件。…

php 字符串处理

addcslashes — 为字符串里面的部分字符添加反斜线转义字符addslashes — 用指定的方式对字符串里面的字符进行转义bin2hex — 将二进制数据转换成十六进制表示chop — rtrim() 的别名函数chr — 返回一个字符的ASCII码chunk_split — 按一定的字符长度将字符串分割成小块conve…

使用前端框架Foundation 4来帮助简化响应式设计开发

日期&#xff1a;2013-3-12 来源&#xff1a;GBin1.com Foundation是一套使用广泛的前端开发套件&#xff0c;可以帮助你快速的网站。最近ZURB发布了一个新版本的Foundation 4前端框架&#xff0c;能够有效的帮助你快速的开发响应式的网站。 和另外一个套知名的前端框架BootSt…

C++网络编程快速入门(二):Linux下使用select演示简单服务端程序

目录select参数解释select使用规范select使用缺点基本流程实例代码通信效果演示往期文章select参数解释 extern int select (int __nfds, fd_set *__restrict __readfds,fd_set *__restrict __writefds,fd_set *__restrict __exceptfds,struct timeval *__restrict __timeout)…

Android转载一:Android文件命名规范

REF&#xff1a;http://blog.csdn.net/gulianchao/article/details/23391651 (一) Layout命名 1&#xff0e;contentview命名&#xff1a;activity_功能模块.xml 例如&#xff1a;activity_main.xml、activity_more.xml 2&#xff0e;Dialog命名&#xff1a;dialog_描述.xml …

[转]XBRL应用软件分类

1) 分类标准编辑软件(Taxonomy editor)&#xff1a; 分类标准是XBRL技术的应用基础&#xff0c;每一个采用XBRL技术的国家都必须先按各国的GAAP制订XBRL分类标准&#xff0c;上市公司才能据以编制实例文件。由于一套XBRL 2.0或2.1版分类标准必须包含至少一份XML Schema文…

C++网络编程快速入门(三):阻塞与非阻塞式调用网络通信函数

目录阻塞与非阻塞定义send与recvconnect一些问题为什么要将监听socket设置为非阻塞阻塞与非阻塞定义 阻塞模式指的是当前某个函数执行效果未达预期&#xff0c;该函数会阻塞当前的执行线程&#xff0c;程序执行流在超时时间到达或者执行成功后恢复原有流程。非阻塞模式相反&am…

css3实现头像旋转360度

css样式: .div a img{ width: 88px; height: 88px; border-radius: 88px; transition: all 1.2s ease-out 0s;}.div a img:hover{ -webkit-transform:rotate(360deg); -moz-transform:rotate(360deg); -o-transform:rotate(360deg); -ms-transform:rotate(360deg); transform:r…

POJ 2488 深搜

POJ 2488 深搜 要求字典序的顺序。 1 #include <iostream>2 #include <stdio.h>3 #include <string.h>4 using namespace std;5 int n,m,cnt;6 bool success;7 bool sign[30][30];8 int step[30][2];9 int dir[8][2]{ 10 -2,-1,-2,1, 11 …

socket 端口和地址复用

https://blog.csdn.net/weibo1230123/article/details/79978745 https://blog.csdn.net/weixin_42157432/article/details/115560824 在linux socket网络编程中&#xff0c;大规模并发TCP或UDP连接时&#xff0c;经常会用到端口复用&#xff1a; int opt 1; if (setsockopt…

MyEclipse老是弹出problem occurred窗口

有的时候是因为jsp页面中的java脚本有误&#xff0c;比如说<% String name"";>就会出现错误&#xff0c;因为结束标签少了一个百分号&#xff05;。转载于:https://www.cnblogs.com/passer1991/archive/2013/03/15/2961624.html

C++网络编程快速入门(四):EPOLL模型使用

目录基本使用方法step1:创建epollfdstep2:将fd绑定到epollfdstep3:调用epoll_wait检测事件epoll_wait与poll、select区别所在水平触发与边缘触发基本使用方法 step1:创建epollfd 创建一个epollfd&#xff0c;若epoll_create调用成功&#xff0c;则返回一个非负值的epollfd&am…

Mysql中代替like模糊查询的一种方法

使用Mysql的函数instr,可代替传统的like方式查询,并且速度更快。 instr函数&#xff0c;第一个参数是字段&#xff0c;第二个参数是要查询的串&#xff0c;返回串的位置&#xff0c;第一个是1&#xff0c;如果没找到就是0. 例如&#xff1a; select username from prefix_user …

两种大小端判断的方式

网络通信是按照字节流进行数据交换的&#xff0c;主机根据不同的CPU型号可能是大段存储&#xff0c;也可能是小端存储。而网络字节序在TCP/IP协议中已经规定好了&#xff0c;采用大端的排序方式。 所以网络通信中一般将需要传输的整数型值转换成网络字节序。 从本机字节序转换成…

把数据库复制成脚本(包含远程以及数据库数据)

1.启动VS 2.服务器资源管理器 3.连接需要的数据库 4.右键数据库 选择publist to provider.... 5.剩下的 选择数据库 选择存放地址 下一步 这方法应该是用在把08的数据还原到05上面 明天用这个方法去盗取哈公司的数据库 看行不行转载于:https://www.cnblogs.com/Rock-Lee/a…