linux下簡單線程池實現

來源:互聯網
上載者:User

/* 標頭檔:threadpool.h*/

#ifndef _TP_H_INCLUDED_

#define _TP_H_INCLUDED_

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <pthread.h>

#include <assert.h>

typedef struct worker {    

  void * (*process) (void *arg);    

  void *arg;    

  struct worker *next;  

} threadpool_item_t;

 

typedef struct {   

     pthread_mutex_t queue_lock;    

   pthread_cond_t queue_ready;    

     threadpool_item_t *queue_head;      

       int shutdown;     /*是否銷毀線程池*/   

       pthread_t *threadid;

         int max_thread_num;/*線程池中允許的活動線程數目*/  

     int cur_queue_size;   /*當前等待隊列的任務數目*/   

} threadpool_t;

 

void pool_init (int max_thread_num);

int  pool_destroy ();

int  pool_add_worker (void * (*process) (void *arg), void *arg);

static void * thread_routine (void *arg);

#endif

 

/*具體實現:threadpool.c*/

#include "threadpool.h"

static threadpool_t *pool = NULL;

/*初始化線程池*/

void pool_init (int max_thread_num) {

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

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

  pthread_cond_init (&(pool->queue_ready), NULL);      

  pool->queue_head = NULL;      

  pool->max_thread_num = max_thread_num;    

  pool->cur_queue_size = 0;      

  pool->shutdown = 0;      

  pool->threadid = (pthread_t *) malloc (max_thread_num * sizeof (pthread_t));

   int i;    

  for (i = 0; i < max_thread_num; i++)    {       

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

    }

}

/*向線程池中加入任務*/

int pool_add_worker (void *(*process) (void *arg), void *arg) {

      /*構造一個新任務*/   

    threadpool_item_t *newworker = (threadpool_item_t *) malloc (sizeof (threadpool_item_t));    

    newworker->process = process;   

    newworker->arg = arg;    

   newworker->next = NULL;

     pthread_mutex_lock (&(pool->queue_lock));

      /*將任務加入到等待隊列中*/    

  threadpool_item_t *member = pool->queue_head;   

   if (member != NULL)   {     

      while (member->next != NULL)    member = member->next;

          member->next = newworker;    

 } else{        

    pool->queue_head = newworker;  

   }     

   assert (pool->queue_head != NULL);     

   pool->cur_queue_size++;    

  pthread_mutex_unlock (&(pool->queue_lock));  

    /*喚醒一個等待線程*/  

   pthread_cond_signal (&(pool->queue_ready));

    return 0;

}

/*銷毀線程池,等待隊列中的任務不會再被執行,但是正在啟動並執行線程會一直把任務運行完後再退出*/

int pool_destroy () {   

   if (pool->shutdown) return -1;/*防止兩次調用*/

    pool->shutdown = 1;      

   /*喚醒所有等待線程,線程池要銷毀了*/    

   pthread_cond_broadcast (&(pool->queue_ready));     

  /*阻塞等待線程退出,否則就成殭屍了*/    

  int i;   

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

     pthread_join (pool->threadid[i], NULL);   

  } 

free (pool->threadid);      

   /*銷毀等待隊列*/  

   threadpool_item_t *head = NULL;   

  while (pool->queue_head != NULL)   

  {       

    head = pool->queue_head;      

     pool->queue_head = pool->queue_head->next;    

      free (head);   

  }   

  /*銷毀條件變數和互斥量*/    

   pthread_mutex_destroy(&(pool->queue_lock));    

   pthread_cond_destroy(&(pool->queue_ready));      

   free (pool);   

   pool=NULL;  

   return 0;

}

/*線程主函數*/

static void * thread_routine (void *arg) {

    printf ("starting thread %lu\n", pthread_self ());    

    while (1)     {  

         pthread_mutex_lock (&(pool->queue_lock));    

       /*如果等待隊列為0並且不銷毀線程池,則處於阻塞狀態;*/       

     while (pool->cur_queue_size == 0 && !pool->shutdown)    

       {          

       printf ("thread %lu is waiting\n", pthread_self ());         

        pthread_cond_wait (&(pool->queue_ready), &(pool->queue_lock));      

       }     

    /*線程池要銷毀了*/       

    if (pool->shutdown)  {           

      /*遇到break,continue,return等跳躍陳述式,千萬不要忘記先解鎖*/           

      pthread_mutex_unlock (&(pool->queue_lock));            

    printf ("thread %lu will exit\n", pthread_self ());            

    pthread_exit (NULL);      

   }       

     printf ("thread %lu is starting to work\n", pthread_self ());      

     assert (pool->cur_queue_size != 0);     

     assert (pool->queue_head != NULL);           

      /*隊列長度減去1,並取出鏈表中的頭元素*/        

  pool->cur_queue_size--;       

   threadpool_item_t *worker = pool->queue_head;      

     pool->queue_head = worker->next;        

     pthread_mutex_unlock (&(pool->queue_lock)); //解鎖       

    /*調用回呼函數,執行任務*/      

     (*(worker->process)) (worker->arg);       

     free (worker);     

    worker = NULL;

    }

}

 

/* 下面是測試代碼 */

void * myprocess (void *arg)

{

   printf ("threadid is 0x%x, working on task %d\n", pthread_self (),*(int *) arg);  

  sleep (1);/*休息一秒,延長任務的執行時間*/  

  return NULL;

}

int main (int argc, char **argv)

{   

  pool_init (3);/*線程池中最多三個活動線程*/      

 

  /*連續向池中投入10個任務*/    

 int *workingnum = (int *) malloc (sizeof (int) * 10);

 int i;   

  for (i = 0; i < 10; i++)   

  {       

      workingnum[i] = i;

       pool_add_worker (myprocess, &workingnum[i]);   

  }    

   /*等待所有任務完成*/     sleep (5);   

  /*銷毀線程池*/     pool_destroy ();     

  free(workingnum);  

workingnum = NULL;   

  return 0;

}

 編譯,運行:

$ gcc -std=c99 -o threadpool threadpool.h threadpool.c -lpthread

$ ./threadpool
starting thread 1115277632
thread 1115277632 is starting to work
threadid is 1115277632, working on task 0
starting thread 1125767488
thread 1125767488 is starting to work
threadid is 1125767488, working on task 1
starting thread 1136257344
thread 1136257344 is starting to work
threadid is 1136257344, working on task 2
thread 1115277632 is starting to work
threadid is 1115277632, working on task 3
thread 1125767488 is starting to work
threadid is 1125767488, working on task 4
thread 1136257344 is starting to work
threadid is 1136257344, working on task 5
thread 1115277632 is starting to work
threadid is 1115277632, working on task 6
thread 1125767488 is starting to work
threadid is 1125767488, working on task 7
thread 1136257344 is starting to work
threadid is 1136257344, working on task 8
thread 1115277632 is starting to work
threadid is 1115277632, working on task 9
thread 1125767488 is waiting
thread 1136257344 is waiting
thread 1115277632 is waiting
thread 1125767488 will exit
thread 1136257344 will exit
thread 1115277632 will exit

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.