代码改变世界

linux c线程池小结

2015-04-15 01:08  枫桥夜泊-霜满天  阅读(234)  评论(0)    收藏  举报

  使用线程池的场景是服务端线程执行时间很短,并且线程的创建和销毁非常频繁,这时候利用线程池可以很好的提升服务端线程,减少线程频繁创建和销毁的开销!

线程池的总体思路是:一个任务队列,若干已经创建好的线程,线程不停的检查任务队列是否有任务,有的话,取出执行,没有就等待,知道任务队列中有任务。

示例代码:

  任务队列结构体:

   typedef struct Job

   {

      void * (*function)(void *arg);      //线程执行实际工作的函数指针

      void* arg;              //函数的参数

      struct job *next             //结构体自引用指针

   }Work;                  //通过该结构体可以创建一个任务队列,用来存储任务

  线程池结构体:

    typedef struct Pool

    {

    int job_cur_num;          //队列中目前的任务数

    int pthread_max_num;       //线程池中线程数目

    int shutDown;           //线程池关闭的标志

    pthread_t * threadid;

    pthread_mutex_t job_mutex;    //线程互池量

    pthread_cond_t job_cond;        //线程条件变量

    Work *jobs;            //任务队列指针

         }Thread_pool;

/******************** 申明函数和变量***********************************/

  static Thread_pool* pool;        //线程池指针

  void* process(void*);          //线程实际工作函数

  void* thread_fun(void*);        //线程执行函数

  void pool_init(int);            //线程池初始化函数

  void pool_add_job(void*(*fun)(void*),void*);    //向任务队列添加任务的函数

  void free_pool();

  void pool_init(int  num)

  {

    int i;

    pool = (Thread_pool*)malloc(sizeof(Thread_pool));

    if(pool == NULL)

    {

      printf("init pool failed\n");

      exit(1);  

    }     

    pool->job_cur_num = 0;

    pool->thread_max_num = num;

    pool->shutDown = 0;

    pool->jobs = NULL;

    pthread_mutex_init(&(pool->job_mutex),NULL);

    pthread_mutex_init(&(pool->job_cond),NULL);

    for(i=0;i<pool->thread_max_num;i++)

    {

        pthread_create(&(pool->threadid[i],NULL,thread_fun,NULL));  

    }

  }

void pool_add_job(void* (*p)(void*arg),void* arg)

{

   Work * w = NULL;

   w = (Work*)malloc(sizeof(Work));

   w->funtion = p;

   w->arg = arg;

   pthread_mutex_init(&(pool->job_mutex));//在这里要上锁,因为pool是全局变量,在其他线程里面也会使用,上锁保证每次操作的唯一性

   Work * temp = pool->jobs;

   if(temp!=NULL)

   {

      while(temp->next!=NULL)

      {

          temp = temp->next;

      }

      temp->next = w;

   }

   else

   {

      pool->jobs = w;

   }

   pthread_mutex_unlock(&(pool->job_mutex));

   pthread_cond_signal(&(pool->job_cond));//通知等待的线程执行任务

}

void* thread_fun(void*arg)//从任务队列里面取出任务,并执行,如果没有,线程进入等待模式

{

  while(1)

  {

    pthread_mutex_lock(&(pool->job_mutex));

    while(pool->job_cur_num == 0 && !pool->shutDown)

    {

      pthread_cond_wait(&(pool->job_cond),&(pool->job_mutex));//如果任务队列没有任务,线程进入等待模式,直到被唤醒,等待后,互斥锁解锁,唤醒后,互斥锁加锁

    }

    Work * job = NULL;

    job = pool->jobs;

    pool->jobs = pool->jobs->next;    

    pthread_mutex_unlock(&(pool->job_mutex));

    (*(job->function))(job->arg);

    free(job);

  }

}

void* process(void*arg)

{

    printf("thread run at 0x%x,task is:%s",(char*)arg);

}

void free_pool()

{

    int i;

    pool->shutDown = 1;

    //销毁线程池中的线程

    pthread_cond_broadcast(&(pool->job_cond));//唤醒所有等待线程

    for(i=0;i<pool->thread_max_num;i++)

    {

      pthread_join(pool->threadid[i],NULL);//等待所有线程执行结束

    }

    free(pool->threadid);//释放内存

    //销毁任务队列呢内容

    Work * temp = NULL;

    temp = pool->jobs;

    while(temp!=NULL)

    {

      free(temp);

      temp = NULL;

      pool->jobs = pool->jobs->next;

      temp = pool->jobs;

    }

    //销毁互斥量和条件变量

    pthread_mutex_destroy(&(pool->job_mutex));

    pthread_cond_destroy(&(pool->job_cond));

    free(pool);

    pool = NULL;

}

int main(int argc,char*argv[])

{  

  int i;

  pool_init(4);  

  pool_add_job(process,"run1");

  pool_add_job(process,"run2");

  pool_add_job(process,"run3");

  pool_add_job(process,"run4");

  pool_add_job(process,"run5");

  pool_add_jobs(process,"run6");

  pool_add_jobs(process,"run7");

  pool_add_jobs(process,"run8");

  pool_add_jobs(process,"run9");

  pool_add_jobs(process,"run10");

  sleep(5);//等待线程执行结束

  free_pool();

  }

  return 0;

}