当前位置: 首页 > news >正文

C++(27): 线程池

目录

1. 概述

2. 例程

(1)ThreadPool.h

(2)ThreadPool.cpp

(3)Start.cpp

(4)编译


1. 概述

线程池技术绝不是C++独有的,Java和Python都有比较晚完善的线程池构造接口。

通俗的讲,线程池只是一种管理线程的方式。很多时候,我们为了充分利用CPU和Memory资源,会创建一些独立的线程,执行同步或异步的任务。但有一个不得不考虑的问题是,现成的创建和销毁本身也是消耗系统资源的,尤其是一些需要频繁创建和销毁线程的应用场景下。当然有时候有一些连续的任务也不需要通过线程池技术来完成。

如上所述,为了避免频繁创建和销毁线程带来的系统资源的消耗,我们可以提前创建一定数量的线程,用来等待和处理队列中的事务,无需反复地创建和销毁线程。

2. 例程

(1)ThreadPool.h

#ifndef __THREADPOOL_H__#define __THREADPOOL_H__#include <iostream>  #include <vector>  #include <queue>  #include <thread>  #include <mutex>  #include <condition_variable>  #include <future>#include <functional>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <stdint.h>class ThreadPool{public:  ThreadPool(size_t threads);template<class F, class... Args>  auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>{using return_type = typename std::result_of<F(Args...)>::type;  auto task = std::make_shared<std::packaged_task<return_type()>>(  std::bind(std::forward<F>(f), std::forward<Args>(args)...)  );  std::future<return_type> res = task->get_future();  {  std::unique_lock<std::mutex> lock(queueMutex);  if (stop) {  throw std::runtime_error("enqueue on stopped ThreadPool");  }  tasks.emplace([task]() { (*task)(); });  }  condition.notify_one();  return res;  }~ThreadPool();private:  std::vector<std::thread> workers;  std::queue<std::function<void()>> tasks;  std::mutex queueMutex;  std::condition_variable condition;  bool stop;  };#endif ///< __THREADPOOL_H__

(2)ThreadPool.cpp

#include "ThreadPool.h"ThreadPool::ThreadPool(size_t threads) : stop(false){for (size_t i = 0; i < threads; ++i) {  workers.emplace_back([this] {  while (true) {  std::function<void()> task;  {  std::unique_lock<std::mutex> lock(this->queueMutex);  this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });  if (this->stop && this->tasks.empty()) {  return;  }  task = std::move(this->tasks.front());  this->tasks.pop();  }  task();  }  });  }  }ThreadPool::~ThreadPool(){  {  std::unique_lock<std::mutex> lock(queueMutex);  stop = true;  }  condition.notify_all();  for (std::thread &worker : workers) {  worker.join();  }  }  

(3)Start.cpp

#include <iostream>  #include <vector>  #include <queue>  #include <thread>  #include <mutex>  #include <condition_variable>  #include <future>#include <functional>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <stdint.h>#include "ThreadPool.h"/** sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread */#define EXTERNAL_FUNC 0 ///< 0: 类内部成员///< 1: 类外部成员#if EXTERNAL_FUNC == 1// 定义一个返回整数的函数  int intFunction(int x){return x * x;}  // 定义一个返回字符串的函数  std::string stringFunction(std::string s){return s + " world";}int main(int argc, char* argv[]){ThreadPool pool(4);  // 使用enqueue来执行intFunction,传入参数4  auto result1 = pool.enqueue(intFunction, 4);  // 使用enqueue来执行stringFunction,传入参数"hello"  auto result2 = pool.enqueue(stringFunction, "hello");  // 获取并打印结果  std::cout << "result1: " << result1.get() << std::endl;  // 应该打印出16  std::cout << "result2: " << result2.get() << std::endl;  // 应该打印出"hello world"  return 0;  }#else ///< 作为类成员class DemoClass{public:  DemoClass(int num_threads = 1){if(num_threads <= 0 ){num_threads = 1;}pool = new ThreadPool(num_threads);}~DemoClass(){delete pool;pool = nullptr;}void printTask(int n){  std::cout << "Processing " << n << std::endl;}  void startProcessing(){for (int i = 1; i <= 50; ++i){pool->enqueue(&DemoClass::printTask, this, i);usleep(1); ///< 短暂的等待是有必要的.}  }private:ThreadPool* pool = nullptr;};  int main(int argc, char* argv[]){DemoClass myClass(10);  myClass.startProcessing();  return 0;  }#endif

(4)编译

sudo g++ -std=c++17 -o ./Start.bin ./*.cpp -lpthread

http://www.lryc.cn/news/424808.html

相关文章:

  • 每日一题-贪心算法
  • PSO 算法实例(手动推导过程)
  • 解决antd TreeSelect 返回值不包含父节点问题 -自定义组件(react)
  • 花四小时,写了个在线实时绘制等值面图小软件,明晚上线,喜欢的小伙伴关注哦
  • c++的vector用法
  • 【Linux网络】Linux网络初探:开启网络世界的大门
  • 目录、用户与组、出错相关函数、时间函数
  • <keep-alive> 一分钟了解
  • Android 启动动画太生硬
  • 深度学习中常用概念总结
  • 进 程
  • Taro-UI
  • TypeScript 之 JavaScript文件类型检查
  • 基本数据类型变量间的自动提升与强制转换以及进制的转换
  • SparseConv 的学习笔记
  • vscode 快速生成vue 格式
  • react笔记:redux
  • 数据结构与算法--图的应用
  • 【leetcode图文详解】特殊数组II : 空间换时间的“记忆化”,越多越好吗?
  • 离线安装prometheus与Grafana实现可视化监控
  • 【Python学习-UI界面】PyQt5 小部件7-QSpinBox 计数器
  • [二次元]个人主页搭建
  • Spring Data JPA 自动创建时间的相关注解和用法
  • Java基础之隐式类型转换
  • 【数据结构与算法 | 图篇】Dijkstra算法(单源最短路径算法)
  • windows c转linux c要做的事情。
  • 【高等代数笔记】002.高等代数研究对象(二)
  • ubuntu服务器部署的mysql本地连不上的问题
  • python redis安装
  • YJ0043定制版抖音电商卷抢购系统带回收商城抖音电商优惠卷投资理财系统