C++11 简单实现线程池的方法

 更新时间:2020年10月27日 12:52  点击:2007

什么是线程池

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

不使用线程池有哪些弊端

创建太多线程,将会浪费一定的资源,有些线程未被充分使用。
销毁太多线程,将导致之后浪费时间再次创建它们。
创建线程太慢,将会导致长时间的等待,性能变差。
销毁线程太慢,导致其它线程资源饥饿。

线程池的组成部分

1、线程池管理器(ThreadPoolManager):用于创建并管理线程池
2、工作线程(WorkThread): 线程池中线程
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。
4、任务队列:用于存放没有处理的任务。提供一种缓冲机制

下面直接看代码实现

ThreadPoolManage.hpp

#pragma once
#include <thread>
#include <vector>
#include <queue>
#include <condition_variable>
#include <mutex>
/*
* 抽象一个任务 根据自己的需求扩展
*/
class AbsTask 
{
public:
 AbsTask() = default;
 virtual ~AbsTask() = default;
public:
 virtual void run() = 0;
};
template<class _Ty>
class ThreadPoolManage
{
public:
 ThreadPoolManage(unsigned int nMaxThread)
 :mMaxThreadNum(nMaxThread)
 , mThreadStatus(false)
 {
 //启动的时候就要创建线程
 auto maxNum = std::thread::hardware_concurrency();
 //获取当前操作系统中CPU的核心数量 根据核心数量来设置 最大工作线程的并发数量
 mMaxThreadNum = mMaxThreadNum > maxNum ? maxNum : mMaxThreadNum;
 //创建工作线程池
 for (auto i = 0; i < mMaxThreadNum; i++)
 {
  mWorkers.emplace_back([this] {
  while (true)
  {
   std::unique_lock<std::mutex> lock(this->mQueue_mutex);
   this->mCondition.wait(lock, [this]() {return this->mThreadStatus || !this->mTasks.empty(); });
   if (this->mThreadStatus && this->mTasks.empty()) 
   { 
   return; 
   }
   //获取队列头部的任务
   auto task = std::move(this->mTasks.front());
   //任务出队
   this->mTasks.pop();
   //执行工作
   task.run();
  }
  });
 }
 }
 ~ThreadPoolManage()
 {

 {
  std::unique_lock<std::mutex> lock(this->mQueue_mutex);
  this->mThreadStatus = true;
 }
 //通知所有线程起来工作 然后退出
 this->mCondition.notify_all();
 //等待所有线程工作完毕
 for (std::thread& worker : this->mWorkers) 
 {
  if (worker.joinable()) {
  worker.join();
  }
 }
 }
 /*
 * 添加任务到任务队列
 */
 void addTask(_Ty& task)
 {
 std::unique_lock<std::mutex> lock(this->mQueue_mutex);
 if (mThreadStatus) {
  throw std::runtime_error("workers stop");
 }
 mTasks.emplace(std::move(task));
 mCondition.notify_one();
 }
private:
 /*
 * 工作线程池
 */
 std::vector<std::thread> mWorkers;
 /*
 * 任务队列
 */
 std::queue<_Ty> mTasks;
 /*
 工作线程的最大并发数量
 */
 unsigned int mMaxThreadNum;
 /*
 条件变量 控制线程池中线程的工作状态
 */
 std::condition_variable mCondition;
 /*
 * 工作线程锁
 */
 std::mutex mQueue_mutex;
 /*
 * 控制线程的开关 false 继续工作 true 退出线程
 */
 bool mThreadStatus;

};

调用代码

main.cpp

#include <iostream>
#include <chrono>
#include "ThreadPool.hpp"
class Task :public AbsTask
{
public:
 void run() override
 {
 std::this_thread::sleep_for(std::chrono::seconds(1));
 std::cout << "works ...... " << std::this_thread::get_id() << std::endl;
 }
};
int main()
{
 ThreadPoolManage<Task> ThreadPool(8);
 for (size_t i = 0; i < 256; i++)
 {
 Task task;
 ThreadPool.addTask(task);
 }
 std::cin.get();
 system("pause");
}

到此这篇关于C++11 简单实现线程池的方法的文章就介绍到这了,更多相关C++11 线程池内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • 基于springcloud异步线程池、高并发请求feign的解决方案

    这篇文章主要介绍了基于springcloud异步线程池、高并发请求feign的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25
  • Java线程池中的各个参数如何合理设置

    这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-19
  • java中多线程与线程池的基本使用方法

    在Java中,我们可以利用多线程来最大化地压榨CPU多核计算的能力,下面这篇文章主要给大家介绍了关于java中多线程与线程池基本使用的相关资料,需要的朋友可以参考下...2021-09-13
  • 教你如何监控 Java 线程池运行状态的操作(必看)

    这篇文章主要介绍了教你如何监控 Java 线程池运行状态的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-27
  • C#多线程ThreadPool线程池详解

    这篇文章主要介绍了C#多线程ThreadPool线程池的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 解决 VSCode 编写 C++11 代码报红问题分析

    今天在写 C++ 代码的时候用上 C++11 的特性,然后发现 VSCode 虽然可以编译通过,但是会在相应位置报红,这是怎么回事呢?下面小编给大家带来了解决方法,一起看看吧...2021-09-27
  • java并发包中CountDownLatch和线程池的使用详解

    这篇文章主要介绍了java并发包中CountDownLatch和线程池的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-18
  • C#线程池用法详细介绍

    在C#编程语言中,使用线程池可以并行地处理工作,当强制线程和更新进度条时,会使用内建架构的ThreadPool类,为批处理使用多核结构,这里我们来看在C#编程语言中一些关于来自System.Threading的ThreadPool的用法的例子...2020-06-25
  • 浅谈Java ThreadPoolExecutor的使用

    今天我们来学习一下Java ThreadPoolExecutor的使用,文中有非常详细的介绍及代码示例,对正在学习Java的小伙伴们有很大的帮助,需要的朋友可以参考下...2021-05-15
  • c++11中regex正则表达式示例简述

    这篇文章主要给大家介绍了关于c++11中regex正则表达式的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c++11具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-04-25
  • 基于C++11的threadpool线程池(简洁且可以带任意多的参数)

    C++11 加入了线程库,从此告别了标准库不支持并发的历史。然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池、信号量等...2020-04-25
  • Java 自定义线程池和线程总数控制操作

    这篇文章主要介绍了Java 自定义线程池和线程总数控制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-27
  • C++11中的原子量和内存序详解

    这篇文章主要给大家介绍了关于C++11中原子量和内存序的相关资料,文中通过示例代码介绍地方非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • c++实现简单的线程池

    本文介绍的线程池采用C++语言,在windows平台下实现。本着技术分享的精神写作本文同时公布源代码。欢迎大家指出该线程池存在的问题并对当前性能进行讨论。...2020-04-25
  • 利用ace的ACE_Task等类实现线程池的方法详解

    本篇文章是对利用ace的ACE_Task等类实现线程池的方法进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • C++线程池的简单实现方法

    这篇文章主要介绍了C++线程池的简单实现方法,包括了线程操作函数及相关属性的用法,需要的朋友可以参考下...2020-04-25
  • C#线程处理系列之线程池中的I/O线程

    这篇文章主要介绍了C#线程处理系列之线程池中的I/O线程,在这篇文章中将介绍如何用线程池中的I/O线程来执行I/O操作,感兴趣的小伙伴们可以参考一下...2020-06-25
  • java 线程池keepAliveTime的含义说明

    这篇文章主要介绍了java 线程池keepAliveTime的含义说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-18
  • C++11中的default函数使用

    这篇文章主要介绍了C++11中的default函数使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-01
  • C++11各种锁的具体使用

    本文主要介绍了C++11各种锁的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-10