C++实现线程池类

* 定义任务类

class Job
{
    Job(void*(*p)(void*),void * a) : process(p),arg(a),next(NULL){}
    void * (* process)(void *);
    void * arg;
    Job * next;
};

任务类的 process 参数是每个线程要执行的函数的指针,arg 为传入该函数的参数


* 定义线程池类

class Pool
{
    friend void * thread_contrl(void*);
    public:

        Pool(int num):max_thread_num(num)  //构造函数必须给出线程池中线程的数量
        {
            pthread_mutex_init(&queue_lock,NULL);
            pthread_cond_init(&queue_cond,NULL);

            threadid = new pthread_t[num];
            shutdown = false;

            for(int i(0); i != num; ++i)
            {
                //线程池中每个线程均执行 thread_contrl(void *) 函数,参数为 Pool*
                //线程通过 thread_contrl 进行调控,并在其内部进行线程任务分配
                pthread_create(&threadid[i],NULL,thread_contrl,this); 
            }
        }

        void add_job(void * (* process)(void *),void * arg)
        {
            Job * temp = new Job(process,arg);

            //在任务队列中增加新任务,需要先通过上锁进行访问
            pthread_mutex_lock(&queue_lock);
            queue_q.push(temp);
            pthread_mutex_unlock(&queue_lock);
            //发送任务进入信号,唤醒等待线程
            pthread_cond_signal(&queue_cond);
        }

        ~Pool()
        {
            if(shutdown)
                return;
            //唤醒所有线程
            pthread_cond_broadcast(&queue_cond);
            for(int i(0); i < max_thread_num; ++i)
            {
                //等待线程结束
                pthread_join(threadid[i],NULL);
            }
            delete []threadid;

            Job * temp = NULL;
            while(!queue_q.empty())
            {
                temp = queue_q.front();
                queue_q.pop();
                delete temp;
                temp = 0;
            }
            pthread_mutex_destroy(&queue_lock);
            pthread_cond_destroy(&queue_cond);
        }

        queue<Job *> queue_q;
        pthread_mutex_t queue_lock;
        pthread_cond_t queue_cond;
        pthread_t * threadid;
        int max_thread_num;
        bool shutdown;   //线程池开关信号
};


* 定义线程控制函数 void * thread_contrl(void * arg)

void * thread_contrl(void * arg)
{
    Pool * pool = reinterpret_cast<Pool *>(arg);
    while(1)
    {
        //需要获得线程池 pool 中的任务,因此在访问任务列表前需要上锁
        pthread_mutex_lock(&pool->queue_lock);

#ifndef WORK    //用于调试信息的输出
        cout << "starting thread : " << pthread_self() << endl;
#endif

        while(pool->queue_q.empty() && pool->shutdown == false)
        {

#ifndef WORK    
            cout << "thread : " << pthread_self() << " is waiting"<< endl;
#endif

            pthread_cond_wait(&pool->queue_cond,&pool->queue_lock);
        }
        if(pool->shutdown)  //线程池关闭信号打开
        {
            pthread_mutex_unlock(&pool->queue_lock);
            pthread_exit(NULL);
        }

#ifndef WORK    
            cout << "thread : " << pthread_self() << " is starting working"<< endl;
#endif

        //从任务列表中领取一项任务
        Job * temp = pool->queue_q.front();
        pool->queue_q.pop();
        pthread_mutex_unlock(&pool->queue_lock);

        //获得任务的线程执行领取的任务
        *(temp->process)(temp->arg);
        delete temp;
        temp = 0;
    }
}


*使用实例:


void * test(void * arg)
{
    int num = reinterpret_cast<int>(arg);
    printf("%d\n",num);

    //***使用 printf 而不使用 cout 的原因之后描述
    sleep(1);
    return NULL;
}

int main()
{
    Pool * pool = new Pool(3);    //建立三线程的线程池
    for(int i (0); i  < 10; ++i)
    {
        pool->add_job(test,reinterpret_cast<void*>(i));
    }
    sleep(6);
    printf("end main\n");
}

输出结果为:每三个连续输出,后停顿一秒,输出下三个,因为线程池中是三线程,此时是三线程同步跑

多线程中使用 printf 而不使用 cout 的原因:printf()函数的输出是一次函数调用,此时输出不会被打断;而cout函数而言,<< 操作符的每次使用都是一次函数调用,有可能在每次<<调用之间线程被调度,使得输出被打断。因此在多线程输出中使用 printf 比使用 cout 好

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值