自己实现C++的线程池

c++11线程池实现 咳咳。c++11 加入了线程库,从此告别了标准库不支持并发的历史。然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池、信号量等。线程池(thread pool)这个东西,在面试上多次被问到,一般的回答都是:“管理一个任务队列,一个线程队列,然后每次取一个任务分配给一个线程去做,循环往复。” 貌似没有问题吧。但是写起程序来的时候就出问题了。 阅读详情

今天见论坛里有问怎么样实现线程池。碰巧原来写过一个类似的。现在来说说。(下面的全是个人理解,不见得是正确的。)

1。先来说说线程池。为什么要使用线程池?
因为创建线程和释放线程是要消耗系统资源的,如果要完成一个工作要不停的创建和释放线程必然会造成很大的系统资源的浪费,所以用线程池。在线程本次工作完成后,不释放线程,让线程等待。再有需要让线程去完成的工作时就把原来创建的线程取过来继续使用。这样节省了重复的创建释放线程的过程。

2。如何实现功能。
根据上面的理解我们来实现这些工作。
A.我们先要创建一个容器来装这些已经创建的线程。
B.然后我们需要用一套机制来让我们知道容器中的线程哪个是空闲的。哪个正在工作。

开始动手写吧.
//.h文件
#ifndef MyThreadPoolH
#define MyThreadPoolH
#include <Classes.hpp>
//定义通讯消息
#define TP_AddThread        WM_USER + 1001 //向容器添加一个线程
#define TP_DeleteThread     WM_USER + 1002 //删除容器中的一个线程
#define TP_GetFreeThread    WM_USER + 1003 //获取一个空闲线程
#define TP_GetThreadCount   WM_USER + 1004 //得到容器中的线程总数

class MyThreadPool : public TObject
{
private:
    HANDLE FHandle;//线程池的句柄 用来接收通讯消。
    TList *FThreadList; //用一个TList来做容器
    bool FError; //是否出现错误
    void __fastcall (TMessage &Message);//消息处理函数
    long __fastcall FGetThreadCount(void);//得到容器中线程的总数
public:
    __fastcall MyThreadPool();
    __fastcall ~MyThreadPool();
__published:
    //发布属性
    __property HNDLE Handle={read=FHandle};
    __property bool Error={read=FError};
    //__property TList *ThreadList={read=FThreadList};//如果有必要把容器发布出来 !但会降低安全性!
    __property long ThreadCount={read=GetFreeThread};
};
#endif

//.cpp
#include <vcl.h>
#pragma hdrstop

#include "MyThreadPool.h"
#pragma package(smart_init)

__fastcall MyThreadPool::MyThreadPool()
{
    FError=false;
    FHandle=AllocateHWnd(MyProc);//创建一个窗口句柄来处理消息
    if(FHandle==NULL)
    {
        FError=true;
        return;
    }
    FThreadList=new TList;//创建容器
    if(FThreadList==NULL)
    {
        FError=true;
        return;
    }
}
__fastcall MyThreadPool::~MyThreadPool()
{
    if(FHandle!=NULL)//释放句柄
    {
        DeallocateHWnd(FHandle);
    }
    if(FThreadList!=NULL)//释放容器
    {//这里只把容器中的线程指针给删除了。
     //中间的线程并没有释放。要释放需要自己添加代码
        FThreadList->Clear();
        delete FThreadList;
    }
}
//处理消息
void __fastcall MyThreadPool::MyProc(TMessage &Message)
{
    void *pThread;
    int ret;
    switch(Message.Msg)
    {
        case TP_AddThread://添加线程的时候消息的WParam参数为线程指针
            pThread=(void *)Message.WParam;
            ret=FThreadList->Add(pThread);
            Message.Result=ret;//返回线程指针在容器中的index
            return;
        case TP_DeleteThread://删除线程时消息的WParam参数为线程指针
            pThread=(void *)Message.WParam;
            ret=FThreadList->IndexOf(pThread);
            //如果线程指针不在容器中返回-1,成功删除返回1
            if(ret==-1)
            {
                Message.Result=-1;
            }
            else
            {
                FThreadList->Delete(ret);
                Message.Result=1;
            }
            return;
        case TP_GetFreeThread://得到一个空闲的线程,如果有空闲消息返回值为线程指针。
            //一但线程给取出线程的Working属性就倍设置成true;
            for(int i=0;i<FThreadList->Count;i++)
            {
                pThreadFThreadList->Items[i];
                if(((TMyThread *)pThread)->Working==false)
                {
                    ((TMyThread *)pThread)->Working=true;
                    Message.Result=(long)pThread;
                    return;
                }
            }
            Message.Result=0;
            return;
        case TP_GetThreadCount://返回容器中的总数
            Message.Result=FThreadList->Count;
            return;
    }
    try
    {
        Dispatch(&Message);
        if(Message.Msg==WM_QUERYENDSESSION)
        {
            Message.Result=1;
        }
    }
    catch(...){};
}

3。我们还需要定制一个自己的线程类来配合上面的ThreadPool来使用

class TMyThread : public TThread
{
private:
    bool FWorking;
    HANDLE PoolHandle
protected:
    void __fastcall Execute();
public:
    __fastcall TMyThread(bool CreateSuspended,HANDLE hHandle/*线程池的句柄*/);
__published:
    //发布属性
    __property bool Working={read=FWorking,write=FWorking};             //线程是否空闲
};

__fastcall TMyThread::TMyThread(bool CreateSuspended,HANDLE hHandle)
    : TThread(CreateSuspended)
{
    PoolHandle=hHandle;
    FWorking=false;   
}
void __fastcall TMyThread::Execute()
{
    while(!Terminated)
    {
        FWorking=true;
        //工作代码
        //。。。。
        FWorking=false;
  this->Suspend();
    }
    ::SendMessage(PoolHandle,TP_DeleteThread,(long)this,0);//在线程池的容器中删除本线程
    return;//线程结束
}

4。下面来演示一下如何使用
//1.创建线程池对象
MyThreadPool *pMyTP=new MyThreadPool;
if(!pMyTP || pMyTP->Error)
{
    //创建出错。
    //。。。处理代码
}
//2.创建N个TMyThread线程对象,并加入线程池
TMyThread *pThread;
for(int i=0;i<N;i++)
{
    pThread=new TMyThread(true,pMyTP->Handle);
    ::SendMessage(pMyTP->Handle,TP_AddThread,(long)pThread,0);        
}
//3.从线程池中去空闲线程
TMyThread *pThread;
pThread=(TMyThread *)::SendMessage(pMyTP->Handle,TP_GetFreeThread,0,0);
if(pThread)//如果有空闲线程
{
    pThread->Resume();  
}        

这样就大致实现了线程池的功能。这种东西我已经用在了程序里了。效果还不错节省了不少资源。但是可能和书上说的线程池还是有很大差别的。
我们暂且叫它线程池A。反正已经达到我开始的时候设计它的目的,节省了资源。
就当是抛砖引玉吧。希望这些代码能给兄弟们一点启发,对兄弟门有用。


C++ 线程池实现原理 背景 多线程编程是C++开发者的一个基本功, 但是很多开发者都是直接使用公司给包装好的线程池库, 没有去了解具体实现,有些实现也都因为高度优化而写得讳莫如深,让初学者看得吃力。 所以写这篇文章主要是想以非常简单的方式讲讲实现原理, 希望初学者看完之后不是觉得「不明觉厉」,而是觉得「原来如此」。 面朝代码 首先先来一段超级简单(注释丰富)的代码展示多线程编程的经典写法。 注: 该段代码和完... 阅读详情

相关推荐

C++新特性实现高效线程池,程序性能瞬间提升!

本文深入探讨了如何利用C++新特性实现高效线程池,提升程序性能。首先介绍了C++11和C++14中提供的新特性,如std::thread、std::future、std::function等,并解释了它们如何用于线程池的实现。然后详细介绍了线程池的设计原理和实现过程,包括任务队列的管理、线程的管理以及线程池的调度策略。通过充分利用C++新特性,使得线程池在高并发场景下表现出色,大大提升了程序的性能和响应速度。

Lion_Long的博客 4245

c++实现线程池

c++实现线程池

tonny的博客 2833

【多线程】实现一个线程池

本期主要讲解: 1.线程池的概念 1.1什么是线程池? 1.2为什么需要线程池? 2.Java标准库自带的线程池 2.1工厂模式 2.2简单使用线程池 3.常见创建线程池的方法 4.ThreadPoolExecutor类 4.1构造方法 4.2拒绝策略 5.实现一个简单的线程池

程序猿教你打篮球的博客 9551

C++实现一个线程池

多线程

sinat_31608641的博客 4590

配置思科交换机冗余链路汇聚

本文对交换机端口汇聚配置进行说明

istrangeboy&begin zero的博客 6684

ADS Layout设计实战:从参数设置到协同仿真

本文详细介绍了ADS Layout设计的完整实战流程,从新建工程、单位设置、个性化偏好配置等基础操作入手,逐步深入到基板参数配置、端口设置与电磁仿真器选择等核心环节。重点阐述了参数化版图设计与扫描优化、以及原理图与Layout协同仿真的高级技巧,并通过一个微带线低通滤波器设计案例,完整演示了从理论到实现的闭环设计方法,帮助工程师高效、准确地完成高频电路版图设计与验证。

weixin_29268637的博客 797

线程池的实现

Linux系统编程的所有知识已经学完了,让我们实现一个线程池,检查我们的学习情况。

qq_65285898的博客 1344

保姆级教程:在STM32H750VBT6上跑起来CMSIS-DSP库(基于CubeMX+Keil)

本文详细介绍了在STM32H750VBT6微控制器上配置和运行CMSIS-DSP库的全过程,包括开发环境搭建、CubeMX工程配置、Keil工程设置以及DSP库的实际应用示例。通过FFT频谱分析和音频均衡器等实战案例,展示了如何利用STM32H750VBT6的硬件FPU加速DSP运算,提升实时信号处理性能。

weixin_30236595的博客 456

C++实现线程池

进程是一个独立的执行单位,每个进程都有自己的独立内存空间,包括代码、数据、堆栈等。进程之间彼此独立,不共享内存,通常通过进程间通信来交换数据。

pan_1214_的博客 4586

超越界面设计:GUI Guider与LVGL在STM32F103上的系统集成与架构思考

本文探讨了GUI Guider与LVGL在STM32F103微控制器上的系统集成与架构设计,重点分析了工程模块化组织、内存管理优化、硬件驱动接口设计以及FreeRTOS多任务集成。针对STM32F103ZET6的资源限制,提供了实用的移植策略和性能优化方案,帮助开发者构建高效、可维护的嵌入式GUI系统。

j2k3l4的博客 921

PHP实战:5分钟搞定SM4国密加密算法集成(附完整代码)

本文提供了一份可直接用于生产环境的PHP SM4国密加密算法集成实战指南。文章详细解析了SM4算法核心,对比了ECB与CBC工作模式,并给出了包含完整代码、密钥管理、数据填充及性能优化的解决方案,帮助开发者快速、安全地在PHP项目中集成国密加密算法。

2a4s6d8f0g的博客 339

cpp线程池的实现

介绍了什么是线程池、及其优点。基于cpp讲解了实现思路、给出实现代码、测试代码。提出未来将要改进的点。

weixin_45007596的博客 1191

流形优化: Manifold Optimization 的 全网最通俗版本详解 (一)

前言 之前忙于论文, 停更了很久。 接下来的一段时间,出于各种原因, 决定在优快云平台上做 最近在 混合波束成形 及 智能反射面 领域 非常常见的流形优化 (Manifold Optimization) 算法 的专题介绍。尽管目前已有了不少的中文博客, 但出于其各种弊端, 使得本篇的成文仍有其不可或缺的意义。 而如果要盘点最核心的意义, 就在于这篇是对读者的 数学能力 与 阅读理解能力 要求最低的 流形优化讲解了。 唯一参考的文献为 Manopt 工具包作者 Boumal 的 新书: An introd

B417科研笔记 2万+

搜集C++实现的线程池

现在很多语言都内置了线程池实现,但C++中却没有。本文列举一些C++实现的线程池工具。 Boost.Threadpool 项目首页:https://threadpool.sourceforge.net Boost.Threadpool是一个基于Boost、跨平台的C++线程池库。Boost.Threadpool提供了一个便捷的任务调度异步的途径。线程池可以定制,动态管理,...

SurpassLi的专栏 83

史上最全!研究生科研必备科研工具(含AI科研工具),附使用说明和示例

这些工具在科研中的应用非常广泛,可以帮助研究生更高效地完成研究任务。为了更好地利用这些工具,建议深入学习它们的官方文档和教程,或者参加相关的工作坊和培训。

智能AI让学术科研更容易 3941

YOLO12涨点改进| 损失函数改进篇 |AAAI 2025| 一种小目标检测SDLoss损失函数,解决现有损失函数对不同目标尺度敏感度不足的局限,提高了网络检测不同尺度目标的敏感能力,助力高效涨点

本文提出了一种改进的小目标检测方法SDLoss,通过动态调整尺度损失与位置损失的权重,优化了YOLOv12模型的性能。针对红外小目标检测中存在的两个主要问题:1)标准卷积难以捕捉目标的高斯空间分布特性;2)现有损失函数对不同尺度目标的敏感度不足,研究团队开发了Pinwheel-shaped卷积(PConv)和Scale-based Dynamic损失函数(SDLoss)。PConv通过不对称卷积核设计显著提升感受野,SDLoss则根据目标大小动态平衡尺度与位置损失的影响。

Ai缝合怪、助力小伙伴高效发论文 238

C++线程池实现

我们试想,如果某类任务的处理时间特别长,但是当前线程需要执行的任务也很多,那么就会导致没有执行完当前任务就无法执行其他任务的现象,极大的降低了工作效率,此时,使用线程池就可以解决掉这个问题,我们可以让其他线程来异步执行这个任务,这样也就极大地提高了效率。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。而且,大量的线程的创建跟销毁会影响系统的性能与资源利用率的,程池的设计思想是为了避免频繁地创建和销毁线程的开销,以及控制并发执行的线程数量,从而提高系统的性能和资源利用率。

2303_77100822的博客 1177

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++ 实现线程池

线程池的基本概念是,在应用程序启动时创建一定数量的线程,并将它们保存在线程池中。当需要执行任务时,从线程池中获取一个空闲的线程,将任务分配给该线程执行。当任务执行完毕后,线程将返回到线程池,可以被其他任务复用。

axyzstra 的博客 1190

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

深入解析CTPL线程池库的example.cpp实现

CTPL是一个轻量级的C++线程池库,提供了简洁高效的线程管理功能。本文将通过分析example.cpp示例代码,全面讲解CTPL线程池的各种使用场景和特性,帮助开发者掌握线程池的高级用法。 ## 线程池基础初始化 示例代码首先展示了如何创建线程池: ```cpp ctpl::thread_pool p(2 /* two threads in the pool */); ``` 这里创建了...

gitblog_00115的博客 956

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【C++】线程池实现

线程池是一种并发编程技术,通过预先创建一组线程并复用它们来执行多个任务,避免了频繁创建和销毁线程的开销。它特别适合处理大量短生命周期任务的场景(如服务器请求、并行计算)。 线程池的核心组件 1. 任务队列(Task Queue) 存储待执行的任务(通常是函数对象或可调用对象)。 2. 工作线程(Worker Threads) 一组预先创建的线程,不断从队列中取出任务并执行。 3. 同步机制 互斥锁(Mutex):保护任务队列的线程安全访问。 条件变量(Condition Variable):通知线程任

AAADiao的博客 2461

C++实现简单线程池

C++实现简易线程池

woodslay的博客 6851

C++线程池的实现

线程池是一种并发编程的技术,用于管理线程资源。线程池需要先预先创建一定数量的线程,当有任务进来的时候,这些线程会去执行对应的任务。当没有任务的时候,线程会在线程池中进行等待,直到有任务进来。线程池的主要目的是避免反复创建和销毁线程的开销,以及有效地控制并发线程的数量。通过使用线程池,可以降低系统的负载,并提高任务执行的效率。当频繁的进行线程的创建和销毁的时候,可以考虑用线程池进行代替。

weixin_47326789的博客 1226

【C/C++】线程池实现

1

IdealSanX的博客 1974

线程池-通过C++实现

用到少量C++11的新特性。 1 池技术 2 线程池 3 线程池组成 5 测试程序

qq_50726065的博客 3641
上一篇: 线程池的介绍及简单实现
下一篇: 用C++Builder建立多线程COM服务器
老白
博客等级 码龄23年 59粉丝 106原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值