构思阶段:

  

1. 线程池的概念:

  线程池的实现原理是这样的:在应用程序启动之后,就马上创建一定数量的线程,放入空闲的队列中。这些线程都是处于阻塞状态,这些线程只占一点内存,不占用CPU。当任务到来后,线程池将选择一个空闲的线程,将任务传入此线程中运行。当所有的线程都处在处理任务的时候,线程池将自动创建一定的数量的新线程,用于处理更多的任务。执行任务完成之后线程并不退出,而是继续在线程池中等待下一次任务。当大部分线程处于阻塞状态时,线程池将自动销毁一部分的线程,回收系统资源。

2. 线程池的工作机制

  2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。

  2.2 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

  2.3 如果所有的线程都处于工作状态,就添加到队列,进行排队。

  2.4 如果队列中的任务个数大于队列的所能容纳的最大数量,那就不能添加任务到队列中,只能等待队列不满才能添加任务到队列中。

代码:

//threadpool.h
#ifndef THREADPOOL_H
#define THREADPOOL_H
 
 
#include<iostream>
#include<pthread.h>
#include<cstdlib>
#include<cassert>
#include<cstdio>
#include<deque>
 
using namespace std;
 
struct Job
{
    void* (*doJobFun)(void *arg);    //线程回调函数
    void *arg;                                //回调函数参数
 
};
 
class ThreadPool
{
    unsigned int threadNum;                   //线程池中开启线程的个数
    unsigned int maxJobNum;                //队列中最大job的个数
    deque<Job> jobQueue;                //任务队列
    pthread_t *pthreads;              //线程池中所有线程的pthread_t
    pthread_mutex_t mutex;            //互斥信号量
    pthread_cond_t condQueueEmpty;       //队列为空的条件变量
    pthread_cond_t condQueueFull;    //队列为满的条件变量
    bool isPoolClose;                   //线程池是否已经关闭
    
public:
    ThreadPool(int threadNum=10, int maxJobNum=100);
    int addJob(Job job);
    int destroy();
    ~ThreadPool();
    friend void* run(void* arg);
};
 
 
 
 
 
 
#endif

 

 

//threadpool.cpp
#include"threadpool.h"
 
 
 
void* run(void* arg)
{
    ThreadPool *pool = (ThreadPool *)arg;
    struct Job job ;
    while (1)  //死循环
    {
        pthread_mutex_lock(&(pool->mutex));
        
        if (pool->isPoolClose)   //线程池关闭,线程就退出
        {
            pthread_mutex_unlock(&(pool->mutex));
            pthread_exit(NULL);
        }
        
        while ((pool->jobQueue.empty()))   //队列为空时,就等待队列非空
        {
            //printf("job queue is empty.....\n");
            pthread_cond_wait(&(pool->condQueueEmpty), &(pool->mutex));
            if (pool->isPoolClose)   //线程池关闭,线程就退出
            {
                pthread_mutex_unlock(&(pool->mutex));
                pthread_exit(NULL);
            }
        }
        
        job=pool->jobQueue.front();
        pool->jobQueue.pop_front();
        //printf("get job %d,size:%d\n",(int)job.arg,pool->jobQueue.size());
        if (pool->jobQueue.size() == (pool->maxJobNum-1))
        {
            pthread_cond_broadcast(&(pool->condQueueFull));  //队列非满,就可以通知threadpool_add_job函数,添加新任务
        }
        pthread_mutex_unlock(&(pool->mutex));
        
        (*(job.doJobFun))(job.arg);   //线程真正要做的工作,回调函数的调用
         
    }
}
 
ThreadPool::ThreadPool(int threadNum, int maxJobNum)
{
    
    
    this->threadNum = threadNum;
    this->maxJobNum = maxJobNum;
    
    if (pthread_mutex_init(&(this->mutex), NULL))
    {
        perror("pthread_mutex_init");
        exit(1);
    }
    
    if (pthread_cond_init(&(this->condQueueEmpty), NULL))
    {
        perror("pthread_cond_init");
        exit(1);
    }
    
    if (pthread_cond_init(&(this->condQueueFull), NULL))
    {
        perror("pthread_cond_init");
        exit(1);
    }
    
    this->pthreads = (pthread_t *)malloc(sizeof(pthread_t) * this->threadNum);
    if (NULL == this->pthreads)
    {
        perror("pthreads malloc");
        exit(1);
    }
    this->isPoolClose = false;
    unsigned int i;
    for (i = 0; i < this->threadNum; ++i)
    {
        pthread_create(&(this->pthreads[i]), NULL, run, (void *)this);
    }
    
    
    
}
 
int ThreadPool::addJob(Job job)
{
    assert(job.doJobFun != NULL);
    //assert(job.arg != NULL);
    if (this->isPoolClose)   //线程池关闭,线程就退出
    {
        return -1;
    }
    pthread_mutex_lock(&(this->mutex));
    while ((this->jobQueue.size() == this->maxJobNum))
    {
        //printf("job queue is full\n");
        pthread_cond_wait(&(this->condQueueFull), &(this->mutex));   //队列满的时候就等待
    }
    if (this->isPoolClose)    //队列关闭或者线程池关闭就退出
    {
        pthread_mutex_unlock(&(this->mutex));
        return -1;
    }
    
    if (this->jobQueue.empty())   
    {
        this->jobQueue.push_back(job);
        pthread_cond_broadcast(&(this->condQueueEmpty));  //队列空的时候,有任务来时就通知线程池中的线程:队列非空
    }
    else
    {
        this->jobQueue.push_back(job);
    }
    //printf("add a job:%d,size:%d\n",(int)job.arg,this->jobQueue.size());
    pthread_mutex_unlock(&(this->mutex));
    
    return 0;
}
 
int ThreadPool::destroy()
{
    //printf("begin destroy...\n");
    pthread_mutex_lock(&(this->mutex));
    this->isPoolClose = true;        //置队列关闭标志
    this->jobQueue.clear();
    
    pthread_mutex_unlock(&(this->mutex));
    pthread_cond_broadcast(&(this->condQueueEmpty));  //唤醒线程池中正在阻塞的线程
    pthread_cond_broadcast(&(this->condQueueFull));   //唤醒添加任务的threadpool_add_job函数
    unsigned int i;
    for (i = 0; i < this->threadNum; ++i)
    {
        pthread_join(this->pthreads[i], NULL);    //等待线程池的所有线程执行完毕
        //printf("thread %X exit.\n",(unsigned int)this->pthreads[i]);
    }
    
    pthread_mutex_destroy(&(this->mutex));          //清理资源
    pthread_cond_destroy(&(this->condQueueEmpty));
    pthread_cond_destroy(&(this->condQueueFull));      
    free(this->pthreads);
    //printf("end destroy...\n");
    return 0;
}
 
ThreadPool::~ThreadPool()
{
    //destroy();
}