线程池总结以及实现

为什么需要线程池:

现在大多数网络服务器,包括Web服务器,Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内处理数目巨大的连接请求,但是处理时间却很短。

如果不用线程池,那么针对每一个请求,我们要花费时间如下

T1:线程创建时间

T2:线程执行时间,包括线程的同步等时间

T3:线程销毁时间

那么每一个线程我们都要话费他的创建时间和销毁时间,那么时间的花费就是(T1+T2)/(T1+T2+T3)若是线程执行时间短,那么这个开销的占比将会很大,而线程池的存在可以帮助我们大大的减少这些问题。


现在线程的机制如下:

首先预创建一些线程,放入空闲队列之中,这些线程都处于阻塞状态不消耗CPU,但占用较小的内存空间,当任务到来后,缓冲池选择一个空闲线程,把任务传入此线程中运行。

当预创建的线程消耗完毕的时候,线程池自动创建一定数量的新线程来处理更多的任务。

任务执行完毕后线程也不会消失,他会继续保持在线程池中等待下一次的任务,当系统比较空闲大部分线程处于暂停状态,线程池自动销毁一部分线程,回收系统资源。



线程池的大体框架:

(1)线程池管理器:创建并管理线程池

(2)工作线程:线程池中实际执行的线程

(3)任务接口:将线程执行的任务抽象出来,形成任务接口,从而使得线程池与具体的任务无关

(4)任务队列:线程池的概念具体到实现则可能是队列,链表之类的数据结构,其中保存执行队列


线程池的实现:

1.两个结构体,一个代表线程池,一个代表线程

typedef struct tpool_work {
   8:     void*               (*routine)(void*);       /* 任务函数 */
   9:     void                *arg;                    /* 传入任务函数的参数 */
  10:     struct tpool_work   *next;                    
  11: }tpool_work_t;
  12:  
  13: typedef struct tpool {
  14:     int             shutdown;                    /* 线程池是否销毁 */
  15:     int             max_thr_num;                /* 最大线程数 */
  16:     pthread_t       *thr_id;                    /* 线程ID数组 */
  17:     tpool_work_t    *queue_head;                /* 线程链表 */
  18:     pthread_mutex_t queue_lock;                    
  19:     pthread_cond_t  queue_ready;    
  20: }tpool_t;
2.应当含有的函数

(1)线程池的创建

(2)线程池的销毁

(3)向线程池中添加任务(由于是线程,所以他的函数参数应该是void*(*routine)(void*))

相当于向任务链表加一个任务,记得通知任务链表条件变量状态idea变化


3.使用的需要的函数

(1)从任务链表取出任务执行

三种情况

(1)线程没有被销毁,没有任务要执行,那么就阻塞

(2)线程池被要求销毁那就销毁

(3)正常执行那么启用任务函数


需要注意的函数

pthread_cond_t cond;

pthread_cond_wait(&cond);

pthread_cond_signal(&cond);

pthread_cond_init(&cond,NULL);

pthread_cond_broadcast(&cond);


对着网上自己写的线程池,容量为6,然后最大活跃的也是6,但是执行10个任务,从输出可以看出来是有的执行完了就走了,然后之后来的任务在原先的内存继续执行

#include
#include
#include
#include


typedef struct thread
{
    void* (*fun)(void* arg);
    void* arg;
    struct thread* next;
}thread;


typedef struct mypool
{
    thread* list;//存放线程的任务链表
    pthread_mutex_t mutex;//加锁防止线程之间陷入恶性竞争
    pthread_cond_t cond;//条件变量,告诉我们什么时候线程需要被启用
    int max_num;//线程池子中最大允许的线程个数
    int cursize;//当前等待队列的任务数目
    int shutdown;//标记线程池是否要被销毁
    pthread_t *thid;//线程组ID
}Tpool;


static Tpool* pool = NULL;


//从任务队列中取出任务执行
static void* threadfun(void* arg)
{
    thread* work;
    while(1)
    {
        pthread_mutex_lock(&pool->mutex);


         while(pool->cursize==0&&pool->shutdown!=1)//阻塞者
         {
               pthread_cond_wait(&pool->cond, &pool->mutex);
         }


         if(pool->shutdown == 1)
         {
             pthread_mutex_unlock(&pool->mutex);
              printf("pthread exit!!!!!!!!!\n");
              pthread_exit(NULL);
         }


         pool->cursize--;
         work = pool->list;
         pool->list = work->next;
         pthread_mutex_unlock(&pool->mutex);


         work->fun(work->arg);
         free(work);
         printf("执行一次任务,删除了一个工做\n");
    }
    return NULL;
}


void Initpool()//初始化线程池
{
     pool = (Tpool*)malloc(sizeof(Tpool));
     pool->max_num = 6;
     pthread_mutex_init(&pool->mutex,NULL);
     pthread_cond_init(&pool->cond,NULL);
     pool->list = NULL;
     pool->cursize = 0;
     pool->thid = (pthread_t*)malloc(6*sizeof(thread));
     int i= 0;
         for(i;i<6;++i)
         {
             pthread_create(&pool->thid[i],NULL,threadfun,NULL);
         }
}


void Destroy()
{
    pool->shutdown = 1;
    pthread_cond_broadcast(&pool->cond);
    int i;
    for(i=0;imax_num;++i)
    {
        pthread_join(pool->thid[i],NULL);
    }
    free(pool->thid);


    thread *member = NULL;
    while(pool->list)
    {
         member = pool->list;
         pool->list = pool->list->next;
         free(member);
    }




    pthread_mutex_destroy(&pool->mutex);
    pthread_cond_destroy(&pool->cond);
    free(pool);


    pool = NULL;
    return ;
}


int pool_add_work(void*(*routine)(void*),void* arg)
{
     thread* work,*member;
     work = calloc(1,sizeof(thread));


     work->fun = routine;
     work->arg = arg;
     work->next = NULL;


     pthread_mutex_lock(&pool->mutex);
     member = pool->list;
     if(!member)//如果member是NULL
     {
          pool->list = work;
     }
     else
     {
          while(member->next)
          {
              member = member->next;
          }
          member->next = work;
     }
     //通知工作者线程有新任务添加
     pool->cursize++;
     pthread_cond_signal(&pool->cond);
     pthread_mutex_unlock(&pool->mutex);
     return 0;


}




void *func(void *arg)
{
    printf("thread %d\n",(int)arg);
    sleep(1);
    return NULL;
}


int main(int arg, char **argv)
{
    Initpool(pool);


    int i= 0;
    for(i;i<10;++i)
    {
         pool_add_work(func,(void*)i);


    }


    sleep(2);
    Destroy();
    return 0;


}

你可能感兴趣的:(线程池总结以及实现)