C++强化之路之线程池开发整体框架(二)

本文介绍了一个C++线程池的开发,包括工作线程、监督线程、任务队列、单例设计模式和回调函数的使用。线程池采用两个任务队列,一个用于等待任务,另一个记录执行中的任务。线程池类设计为单例,确保程序中只有一个实例。回调函数用于预注册任务。此外,文章还详细讨论了线程池的具体实现,包括线程的创建、任务调度及线程池动态调整。最后展示了测试程序的运行结果。
摘要由CSDN通过智能技术生成

一.线程池开发框架

我所开发的线程池由以下几部分组成:
1.工作中的线程。也就是线程池中的线程,主要是执行分发来的task。
2.管理线程池的监督线程。这个线程的创建独立于线程池的创建,按照既定的管理方法进行管理线程池中的所有线程,主要任务是监听任务的到来,唤醒线程池中的空闲线程,分发任务;如果任务增多,动态的创建一批线程加入原来的线程池中,进行工作;适当的销毁线程,减少系统开销。

这个线程池的开发涉及了以下几个数据结构、设计模式和软件结构:
1.任务队列。整个框架有两个任务队列,1)等待任务队列(以下简称wait_queue)。2)正在执行中任务队列(以下简称doing_queue)。队列采用先进先出的数据结构。当一个任务来到时,会先被push到wait_queue,监督线程会一直监督wait_queue中的元素,一旦有任务,便会pop wait_queue中的元素,再push到doing_queue中。
2.单例设计模式。线程池的类被设计成单例模式,防止一个程序中多次创建线程池对象,出现紊乱现象,用户只能调用静态方法初始化得到线程池的对象。
3.回调函数。回调函数的设计主要是为了能够把任务接口(也就是需要线程去执行的任务,通常是一个写好的函数方法)提前初始化注册,然后延迟调用。

下图是所用类的的大概结构图:
这里写图片描述

程序整体结构如下:
这里写图片描述

二.线程池开发具体实现

1.思路分析。
线程池顾名思义就是同时有数个线程处于待执行状态,编码上的初始化的实现无非就是循环创建指定数量的线程,然后等待任务的到来唤醒空闲线程。以下是ThreadPoll的类:

class ThreadPool 
{
    private:
        pthread_t *_thread;  //线程池
        pthread_t *_thread_bak; //备用线程池,当任务过多会自动创建
        pthread_t taskqueue_thread; //管理线程

        int u4sequence;
        int wait_time;
        int CANCEL_SIGNAL;
        bool F_improve_ThrdPoll; //备用线程池创建标志
        Mutex *mutex;  //互斥锁
        CondThread *task_cond; //条件变量

        TaskFuncCallback callback; //声明回调函数,即线程所需要执行的函数

        int _num_threads;  //线程池数量

        //构造函数的实现为private属性,禁止用户用构造函数初始化对象。
        ThreadPool(int num_threads):_num_threads(num_threads),
            F_improve_ThrdPoll(0),
            wait_time(0),
            u4sequence(0),
            CANCEL_SIGNAL(0){
        init(); //一些变量的创建
        ManagerThreadInit(); //创建管理线程
        ThreadPoolInit(num_threads);//初始化线程池
        }

    public:
        LVQueue<TASK_QUEUE_T> task_wait_queue;//创建任务等待队列
        LVQueue<TASK_QUEUE_T> task_doing_queue;//创建任务执行队列

        ~ThreadPool(){
            delete(mutex);
            delete(task_cond);
            delete(_thread);
            delete(_thread_bak);

        }
        //用户通过调用此静态方法得到线程池的对象(单例模式)
        static ThreadPool* createThreadPool(int num)
        {   
            static ThreadPool *_pool = new ThreadPool(num);
            return _pool;
        }
        void init(){

            _thread = new pthread_t[_num_threads];
            mutex = new Mutex();
            task_cond = new CondThread();

        }
        API_RETURN_TYPE_T ThreadPoolInit(int num_thr);//线程池初始化,核心接口
        API_RETURN_TYPE_T run(); //线程执行函数
        API_RETURN_TYPE_T ManagerThreadInit();//管理线程初始化
        API_RETURN_TYPE_T managerThread();线程执行函数
        API_RETURN_TYPE_T wakeupThread(TaskFuncCallback p_func);//用户调用此接口唤醒线程执行任务,参数为传入的任务执行函数地址
        API_RETURN_TYPE_T AutoComputeOptimumThreadNum(int wait_que_num,int &_u4sequence);//一种自动计算需要增加多少线程到线程池,当任务繁多时会调到。
        API_RETURN_TYPE_T ThreadJoin();//所有线程阻塞
        API_RETURN_TYPE_T ReleaseSubThreadPool();//释放备用线程池
        API_RETURN_TYPE_T DestroyThreadPool();//释放线程池       
};

下面是cpp的实现:

//线程池初始化的实现
API_RETURN_TYPE_T ThreadPool::ThreadPoolInit(int num_thr)
{
    printf("num = %d.\n",num_thr);  
    if(num_thr == 0)
    {
        return API_SUCCESS;
    }
    //设置创建线程的属性为DETACHED,线程被释放后,资源会被回收。
    pthread_attr_t attr;
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);

    int i = 0;
    if(F_improve_ThrdPoll == 1)//备用线程池创建的标志位,初始化线程不会走这边
    {
        _thread_bak = new pthread_t[num_thr];
        for(;i < num_thr;i++)
        {
            if(RET_OK != pthread_create(&(_thread_bak[i]), &attr, &thread_func, this))
            {
                return API_FAIL;
            }
        }
        return API_SUCCESS;
    }
    //create thread pool.
    for(;i < num_thr;i++)
    {
        if(RET_OK != pthread_create(&(_thread[i]), &attr, &thread_func, this))
        {
            return API_FAIL;
        }
    }

    pthread_attr_destroy (&attr);
    return API_SUCCESS;
}
//创建的所有线程都会跑到这个线程函数,最终指向run
void  *thread_func(void *arg)
{
    ThreadPool *thread = (ThreadPool*)arg;
    thread->run();
}
//线程池核心内容
API_RETURN_TYPE_T ThreadPool::run()
{
    
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值