C++(27): 线程池

embedded/2024/9/23 11:21:05/

目录

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.ppmy.cn/embedded/95728.html

相关文章

python实现每天定时发送邮件

文章目录 步骤 1: 安装所需的库步骤 2: 编写发送电子邮件的 Python 脚本步骤 3: 配置电子邮件发送服务步骤 4: 运行脚本进一步扩展 要编写一个用于自动发送每日电子邮件报告的 Python 脚本&#xff0c;并配置它在每天的特定时间发送电子邮件&#xff0c;使用 smtplib 和 emai…

three.js 几何体、材质和网格模型

场景Scene、相机Camera、渲染器Renderer初始化完成之后&#xff0c;可以向场景中添加一个简单的模型进行展示。在此之前需要了解三个概念&#xff1a;几何体、材质、网格模型。 几何体&#xff1a;表示物体的几何形状。材质&#xff1a;表示物体的外观效果。网格模型&#xff…

股指期权双卖策略

#!/usr/bin/env python # coding:utf-8 from PoboAPI import * import datetime import time import numpy as np from copy import *import pandas as pd #设定持仓细节数据表 #g.df = {}g.df = pd.DataFrame(columns = [date,code,price,volume,stoploss,iv]) g.df2 = pd.Dat…

HTTP的认证方式

0.HTTP认证相关的一些基本概念 0.1 HTTP保护空间(HTTP Protection Space) 也称为认证领域(Authentication Realm),是指在HTTP认证中用来定义一组受保护资源的范围。保护空间通常由一个realm标识符来表示,它定义了用户需要提供凭据(如用户名和密码)才能访问的资源集合…

18705 01背包问题

### 分析 这是一个典型的0/1背包问题。我们需要在有限的背包容量下&#xff0c;选择若干物品&#xff0c;使得获得的总价值最大。可以使用动态规划来解决这个问题。 ### 伪代码 1. 定义一个一维数组dp&#xff0c;其中dp[j]表示容量为j的背包能获得的最大价值。 2. 初始化dp[0…

安企CMS多站点迁移教程

安企CMS多站点中默认站点迁移教程 登录安企CMS后台&#xff0c;在功能管理中找到 备份与恢复 功能&#xff0c;并新增一条备份记录。这么做是为了将数据库中的数据备份成文件。回到宝塔面板&#xff0c;找到 网站&#xff0c;切换到 GO项目 找到需要迁移的站点&#xff0c;点击…

从零开始搭建k8s集群详细步骤

声明&#xff1a;本文仅作为个人记录学习k8s过程的笔记。 节点规划&#xff1a; 两台节点为阿里云ECS云服务器&#xff0c;操作系统为centos7.9&#xff0c;master为2v4GB,node为2v2GB,硬盘空间均为40GB。&#xff08;节点基础配置不低于2V2GB&#xff09; 主机名节点ip角色部…

Windows 10/11和Linux双系统用户请勿安装最新更新 否则将无法启动

据蓝点网报道&#xff0c;Windows 10/11 最新累积更新存在已知问题&#xff0c;如果你同时安装了 Linux 双系统则会在更新后导致系统无法正常启动。 启动时会出现如下报错&#xff1a; Verifiying shim SBAT data failed: Security Policy Violation.Something has gone serio…