Linux C 实现线程池

来源:互联网 发布:前海人寿校招 知乎 编辑:程序博客网 时间:2024/04/29 09:23

最近做的一些工作需要用到线程池技术,因此参考了一些资料和书籍,如《0bug c/c++商用工程之道》。

为此在linux平台上用纯c写了一个线程池的实现。

 

在此列出了原代码。

 

主要用到的数据结构有

1.struct  thread_pool_t    // thread pool 的实现代码

2.struct thread_pool_token_t    //在thread pool 中用到的结构,一个该类型变量代表一条线程

3.struct thread_pool_job_t     //当线前程处理该任务将回调结构

 

设计思路:

主线程创建线程池的控制线程,

管理线程将进入循环来做以下事情:

1.如果当前空闲进程不足并且总线程数没有达到上限,将创建一条空闲线程,至道空闲线程达到3条(见THREAD_POOL_MIN_IDLE_SIZE)

2.不断检查工作任务队列,有则安排一条空闲线程对该任务进行处理

 

普通线程被管理线程创建后也将进入循环来做以下事情:

1.检查当前assign的thread_pool_token_t结构的状态,如果是TREAD_POOL_STATE_BUSY则调用thread_pool_token_t所注册的回调函数来处理任务。

2.完成该任务后检测当前空闲进程够不够,如果太多则退出本线程,否则会改写运行状态为TREAD_POOL_STATE_IDLE后继续循环

 

注册任务:

1.当没有空闲线程可用时将把该任务加入工作任务队列(需定义_THREAD_POOL_JOB_LIST_),以备将来有空闲线程是能够进行处理。

 

 

主要文件 :

1.thread_pool.h

 
#ifndef _LIB_DOL_THREAD_POOL_H_
#define _LIB_DOL_THREAD_POOL_H_

#include "thread_pool.def"

#include <pthread.h>

#define THREAD_POOL_MIN_SIZE      5     /* at least 5 threads, 4 job + 1 manage thread */
#define THREAD_POOL_MIN_IDLE_SIZE 3     /* at least 3 threads idle to improve the efficiency */
#define THREAD_POOL_DEFAULT_SIZE  10    /* default threads in thread pool */
#define THREAD_POOL_MAX_SIZE      100   /* max threads in thread pool */

#define TREAD_POOL_STATE_NOTRUN   0
#define TREAD_POOL_STATE_IDLE     1
#define TREAD_POOL_STATE_BUSY     2

#define TREAD_POOL_REG_OK         0
#define TREAD_POOL_REG_ERR        -1
#define TREAD_POOL_REG_ERR_FULL   -2

#define ETPNOUSE      -2   /* thread pool can not use */
#define ETPERR        -1   /* thread pool over flow */
#define ETPOK          0   /* thread pool register ok */

#define CREATE_THREAD_SLEEP   ( 200 * 1000 //200ms
#define LOOP_SLEEP            ( 150 * 1000 //150ms

typedef void (*job_call_back_t)(void * );

typedef struct _thread_pool_job{
   /* call back function which the thread will call to process this job */
   job_call_back_t call_back;

   /* parameter for call back function */
   void * param;

   /* job desc */
   char desc[64];

#ifdef _THREAD_POOL_JOB_LIST_
   /* if too many job then we will use this list to store the other job */
   struct _thread_pool_job* next;
#endif
}thread_pool_job_t;

struct _thread_pool;

typedef struct _thread_pool_token{
   int                  token_id;
   int                  state;
   int                  total_job; /* total jobs */
   pthread_t            thread_id;
   thread_pool_job_t*  job;
   struct _thread_pool* pool;
   pthread_mutex_t      lock;
} thread_pool_token_t;

typedef struct _thread_pool{
   int  size;         /* thread pool size */
   int  active;       /* total create thread count */
   int  busy;         /* total busy thread count */
   int  idle;         /* total idle thread count */
   int  quit;         /* should we quit the thread 1-quit, 0-loop */
   int  total_job;   /* total process register job */
   int  reg_err;      /* total register err */

#ifdef _THREAD_POOL_JOB_LIST_
   /* use a link list to buff job if too many jobs are registered */
   thread_pool_job_t* job_head;
   /* lock for manuplate job list */
   pthread_mutex_t     job_lock;
#endif

   /* lock */
   pthread_mutex_t     pool_lock;

   /* thread pool core data */
   thread_pool_token_t token[THREAD_POOL_MAX_SIZE];
}thread_pool_t;

/*
* init a thread pool with pool_size threads
* if pool_size is 0 or less than THREAD_POOL_IDLE_SIZE then pool_size set to THREAD_POOL_DEFAULT_SIZE
* if pool_size is larger than THREAD_POOL_MAX_SIZE then pool_size set to THREAD_POOL_MAX_SIZE
* return 0 if ok, -1 if error
*/
int thread_pool_init(thread_pool_t * pool, int pool_size);

/*
* thread pool destroy
*/
void thread_pool_destroy(thread_pool_t * pool);

/*
* pool      -   the thread pool
* call_back -   call back function for thread token to call
* param     -   call back function parameter
* desc      -   tsk description
* it's thread safe when multi thread register thread pool job
*/
int thread_pool_register_job(thread_pool_t * pool, job_call_back_t call_back, void * param, char* desc);

/*
* out put the pool statistic data to stdout
*/
void thread_pool_statistic(thread_pool_t * pool);

/*
* out put the pool run time data to stdout
*/
void thread_pool_runtime(thread_pool_t * pool);

/*
* change the default log file to log_file
*/
void thread_pool_set_log(char* log_file);

/* thread pool token thread serve function */
static void * thread_pool_serve(void * arg);

/* thread pool control thread function */
static void * thread_pool_manage(void * arg);

/* destroy the mutex lock */
static void thread_pool_clean_up_lock(thread_pool_t * pool);

/* thread pool log */
static void thread_pool_log(char* fmt, ...);

/*
*  find a not use token
*  -1 if not found , else the token index
*/
static int thread_pool_find_free_token(thread_pool_t * pool);

/*
*  find a runing and idle token
*  -1 if not found , else the token index
*/
static int thread_pool_find_serve_token(thread_pool_t * pool);

#ifdef _DEBUG_VERSION_
   #define _DOL_FPRINTF_ fprintf
#else
   #define _DOL_FPRINTF_ //fprintf
#endif

#ifdef _THREAD_POOL_JOB_LIST_
/* pop a job from job list */
static thread_pool_job_t* pop_job(thread_pool_t * pool);

/* push a job in job list */
static void push_job(thread_pool_t * pool, thread_pool_job_t* job);

/* destroy the job list */
static void destroy_job_list(thread_pool_job_t* job_head);
#endif

#endif // end if define _LIB_DOL_THREAD_POOL_H_

 2. thread_pool.c

 

//COPYRIGHT AND PERMISSION NOTICE //Copyright (c) 2010, Dolphin Cheung, <dolphin98629@163.com>. //All rights reserved. //Permission to use, copy, modify, and distribute this software for any purpose//with or without fee is hereby granted, provided that the above copyright//notice and this permission notice appear in all copies. //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN//NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,//DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR//OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE//OR OTHER DEALINGS IN THE SOFTWARE. //Except as contained in this notice, the name of a copyright holder shall not//be used in advertising or otherwise to promote the sale, use or other dealings//in this Software without prior written authorization of the copyright holder.
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <errno.h>#include <time.h>#include <stdarg.h>#include <string.h>#include "thread_pool.h"static const char * default_log_file = "/var/log/libdol_tp.log";static char real_log_file[256];/* thread pool token thread serve function */static void * thread_pool_serve(void * arg){   thread_pool_token_t* token = (thread_pool_token_t*) arg;   int self_quit = 0;   token->state = TREAD_POOL_STATE_IDLE;   pthread_mutex_lock(&(token->pool->pool_lock));   token->pool->idle ++;   token->pool->active++;   pthread_mutex_unlock(&(token->pool->pool_lock));   usleep(LOOP_SLEEP);   thread_pool_log("serve thread create: token:%d thread:%u pid:%d ppid:%d",token->token_id, token->thread_id,(int)getpid(),(int)getppid());   while(! token->pool->quit){      /* do we have job ? */      if(token->state == TREAD_POOL_STATE_BUSY         && token->job && token->job->call_back){         /* modify pool stat. */         pthread_mutex_lock(&(token->pool->pool_lock));         token->pool->idle --;         token->pool->busy ++;         token->pool->total_job ++;         pthread_mutex_unlock(&(token->pool->pool_lock));         /*          * process this job; this job may be a daemon process          * so it may process all the time, you should design carefully          * when it's time to quit in the while loop for the daemon process          * the thread pool have no way to tell the daemon process we will quit          * so when quit the thread pool, you also need to tell your           * daemon process to quit.          */         token->job->call_back(token->job->param);         pthread_mutex_lock(&(token->lock));         token->total_job ++;         free(token->job);         token->job = NULL;         token->state = TREAD_POOL_STATE_IDLE;         pthread_mutex_unlock(&(token->lock));                  /* modify pool stat. */         pthread_mutex_lock(&(token->pool->pool_lock));         token->pool->idle ++;         token->pool->busy --;         /* too many idle thread ? */         if(token->pool->idle > THREAD_POOL_MIN_IDLE_SIZE){            self_quit = 1;         }         pthread_mutex_unlock(&(token->pool->pool_lock));      }      if(self_quit){         break;      }      usleep(LOOP_SLEEP);   }   thread_pool_log("serve thread quit: token:%d thread:%u job:%d pid:%d ppid:%d",      token->token_id, token->thread_id,token->total_job,(int)getpid(),(int)getppid());   //thread quit   pthread_mutex_lock(&(token->lock));   token->state = TREAD_POOL_STATE_NOTRUN;   token->thread_id = 0;   pthread_mutex_unlock(&(token->lock));   pthread_mutex_lock(&(token->pool->pool_lock));   token->pool->idle --;   token->pool->active --;   pthread_mutex_unlock(&(token->pool->pool_lock));   return NULL;}/* thread pool control thread function */static void * thread_pool_manage(void * arg){   thread_pool_t *pool = (thread_pool_t*) arg;   thread_pool_job_t* job_node;   int i, rc , idle, active,busy;   if(pool == NULL){      thread_pool_log("WARNING: thread_pool_manage stop when pool is NULL");      return NULL;   }   pool->active++;   usleep(CREATE_THREAD_SLEEP );   thread_pool_log("manage thread create. pid:%d ppid:%d",(int)getpid(),(int)getppid());   while(! pool->quit){      pthread_mutex_lock(&(pool->pool_lock));      idle = pool->idle;      active = pool->active;      busy = pool->busy;      pthread_mutex_unlock(&(pool->pool_lock));      if( idle < THREAD_POOL_MIN_IDLE_SIZE){         //less than preset idle thread then create new therad         if(active < pool->size){            //ok we can create new thread now            i = thread_pool_find_free_token(pool);            if(i == -1){               //sorry , it's unusual case               _DOL_FPRINTF_(stderr,"WARNING: can not found free token/n");               thread_pool_log("WARNING: can not found free token when create new thread");            }else{               rc = pthread_create(&(pool->token[i].thread_id), NULL, &thread_pool_serve, &(pool->token[i]));               if(rc !=0 ){                  fprintf(stderr,"ERROR: thread pool create serve thread fail! code[%d] desc[%s]/n",errno,strerror(errno));                  thread_pool_log("ERROR: thread pool create serve thread fail! code[%d] desc[%s]/n",errno,strerror(errno));                  pthread_mutex_lock(&(pool->token[i].lock));                  pool->token[i].state = TREAD_POOL_STATE_NOTRUN;                  pthread_mutex_unlock(&(pool->token[i].lock));               }               usleep(CREATE_THREAD_SLEEP );            }         }else{            //sorry we're too busy            _DOL_FPRINTF_(stdout,"WARNING: no more idle thread, total:%d idle:%d busy:%d nrun:%d/n",active,idle,busy,active-idle-busy-1);            thread_pool_log("WARNING: we're busy, total:%d idle:%d busy:%d nrun:%d",active,idle,busy,active-idle-busy-1);         }      }#ifdef _THREAD_POOL_JOB_LIST_      while(job_node = pop_job(pool)){         i = thread_pool_find_serve_token(pool);         if(i == -1){            /* we will break the loop if no more serve token found and push back the job */            push_job(pool,job_node);            break;         }else{            pthread_mutex_lock(&(pool->token[i].lock));            /* make the register thread safe */            if(pool->token[i].state == TREAD_POOL_STATE_IDLE){               pool->token[i].job = job_node;               /* set thread state to busy and the thread will process the job */               pool->token[i].state = TREAD_POOL_STATE_BUSY;            }else{               push_job(pool,job_node);            }            pthread_mutex_unlock(&(pool->token[i].lock));         }      }#endif      usleep(LOOP_SLEEP );   }   /* wait for other serve thread to terminal */   while(pool->active > 1){      usleep(LOOP_SLEEP );   }   thread_pool_clean_up_lock(pool);   thread_pool_log("thread pool manage thread terminal! pid:%d ppid:%d",(int)getpid(),(int)getppid());   pool->active --;   return NULL;}void thread_pool_set_log(char* log_file){   if(log_file == NULL)      return;   if(strlen(log_file) > sizeof(real_log_file))      return;   strcpy(real_log_file,log_file);}/* thread pool log */static void thread_pool_log(char* fmt, ...){   va_list args;   FILE * fo;   char date[32], ttime[32], filename[128], fpath[128];   char buffer[1024];   time_t tnow;   struct tm * tm_time;   time(&tnow);   tm_time = localtime(&tnow);   strftime(date, sizeof(date), "%y%m%d", tm_time);   strftime(ttime, sizeof(ttime), "%H%M%S", tm_time);   sprintf(filename, "%s", real_log_file);   //if(access(filename, F_OK) != 0){      //mkdir(fpath, 00777);      //chmod(fpath, 00777);   //}   //chmod(filename, 00666);   if((fo = fopen(filename, "a")) == 0){      fprintf(stderr,"cannot open %s", fo);      return;   }   va_start(args,fmt);   vsprintf(buffer,fmt,args);   fprintf(fo,"%s %s/n",ttime,buffer);   va_end(args);   fclose(fo);}int thread_pool_init(thread_pool_t * pool, int pool_size){   int rc,i;   pthread_t  tid;   if(pool == NULL){      return ETPNOUSE;   }   memset(pool,0x00,sizeof(thread_pool_t));   memset(real_log_file,0x00,sizeof(real_log_file));   sprintf(real_log_file,"%s",default_log_file);   /* at least */   if(pool_size < THREAD_POOL_MIN_SIZE)      pool_size = THREAD_POOL_DEFAULT_SIZE;   else if(pool_size >= THREAD_POOL_MAX_SIZE )      pool_size = THREAD_POOL_MAX_SIZE;   pool->size = pool_size;   thread_pool_log("thread pool init with size:%d",pool->size);   pthread_mutex_init(&(pool->pool_lock),NULL);#ifdef _THREAD_POOL_JOB_LIST_   pthread_mutex_init(&(pool->job_lock),NULL);   pool->job_head = NULL;#endif   for(i=0;i<pool_size;i++){      pthread_mutex_init(&(pool->token[i].lock),NULL);      pool->token[i].token_id = i;      pool->token[i].state = TREAD_POOL_STATE_NOTRUN;      pool->token[i].job = NULL;      pool->token[i].pool = pool;   }   /* only create the manager thread, and it will create other serve threads */   rc = pthread_create(&tid, NULL, &thread_pool_manage, pool);   if(rc !=0 ){      fprintf(stderr,"ERROR:thread pool create fail! code[%d] desc[%s]/n",errno,strerror(errno));      thread_pool_log("ERROR:thread pool create fail! code[%d] desc[%s]/n",errno,strerror(errno));      pthread_mutex_destroy(&(pool->pool_lock));#ifdef _THREAD_POOL_JOB_LIST_      pthread_mutex_destroy(&(pool->job_lock));#endif      for(i=0;i<pool_size;i++){         pthread_mutex_destroy(&(pool->token[i].lock));;      }      return ETPERR;   }else{      _DOL_FPRINTF_(stdout,"thread pool create manage thread %u completed/n",tid);   }   usleep(CREATE_THREAD_SLEEP);   return ETPOK;}void thread_pool_destroy(thread_pool_t * pool){   if(pool == NULL)      return;   pool->quit = 1;   while(pool->active){      usleep(LOOP_SLEEP );      _DOL_FPRINTF_(stdout,"Still have %d threads in thread pool/n",pool->active);   }#ifdef _THREAD_POOL_JOB_LIST_   destroy_job_list(pool->job_head);#endif   thread_pool_log("thread pool destroy! terminal %d threads; total %d jobs",pool->size, pool->total_job);}int thread_pool_register_job(thread_pool_t * pool, job_call_back_t call_back, void * param, char* desc ){   int i=0,rc;   thread_pool_job_t* job = (thread_pool_job_t*)malloc(sizeof(thread_pool_job_t));   if(job == NULL){      /* no more memory */      return TREAD_POOL_REG_ERR;   }   memset(job,0x00,sizeof(thread_pool_job_t));   job->call_back = call_back;   job->param = param;   if(desc)      sprintf(job->desc,"%s",desc);   else      sprintf(job->desc,"N/A");   i = thread_pool_find_serve_token(pool);   if(i == -1){#ifdef _THREAD_POOL_JOB_LIST_      job->next = NULL;      push_job(pool,job);      return TREAD_POOL_REG_OK;#else      if(job)         free(job);      pool->reg_err ++;      return TREAD_POOL_REG_ERR_FULL;#endif   }   pthread_mutex_lock(&(pool->token[i].lock));   /* make the register thread safe */   if(pool->token[i].state == TREAD_POOL_STATE_IDLE){      pool->token[i].job = job;      /* set thread state to busy and the thread will process the job */      pool->token[i].state = TREAD_POOL_STATE_BUSY;      rc = TREAD_POOL_REG_OK;   }else{      pool->reg_err ++;      rc = TREAD_POOL_REG_ERR;   }   pthread_mutex_unlock(&(pool->token[i].lock));   return rc;}static void thread_pool_clean_up_lock(thread_pool_t * pool){   int i;   if(pool == NULL)      return;   for(i=0; i<pool->size; i++){      pthread_mutex_destroy(&(pool->token[i].lock));   }   pthread_mutex_destroy(&(pool->pool_lock));#ifdef _THREAD_POOL_JOB_LIST_   pthread_mutex_destroy(&(pool->job_lock));#endif}void thread_pool_statistic(thread_pool_t * pool){   if(pool == NULL){      _DOL_FPRINTF_(stderr,"thread_pool_statistic(NULL)/n");      return;   }   fprintf(stdout,"/n     *** thread pool statistic ***/n");   fprintf(stdout,"     size:%d/t job:%d/t reg_err:%d/n     active:%d/t busy:%d/t idle:%d/t/n"          ,pool->size,pool->total_job,pool->reg_err,pool->active,pool->busy,pool->idle);}void thread_pool_runtime(thread_pool_t * pool){   int i;   thread_pool_job_t* job;   char state[16];   if(pool == NULL){      _DOL_FPRINTF_(stderr,"thread_pool_runtime(NULL)/n");      return;   }   pthread_mutex_lock(&(pool->pool_lock));   fprintf(stdout,"/n     *** thread pool runtime ***");   fprintf(stdout,"/n     size:%d/t job:%d/t reg_err:%d/n     active:%d/t busy:%d/t idle:%d/t/n"          ,pool->size,pool->total_job,pool->reg_err,pool->active,pool->busy,pool->idle);   pthread_mutex_unlock(&(pool->pool_lock));   fprintf(stdout,"/n     id/t tid/t job/t stat/t desc/n");   for(i=0; i<pool->size; i++){      pthread_mutex_lock(&(pool->token[i].lock));      if(pool->token[i].state != TREAD_POOL_STATE_NOTRUN){         fprintf(stdout, "     %d/t %u/t %d/t ",            pool->token[i].token_id,pool->token[i].thread_id,pool->token[i].total_job);         if(pool->token[i].state == TREAD_POOL_STATE_NOTRUN){            sprintf(state,"NOTRUN");         }else if(pool->token[i].state == TREAD_POOL_STATE_IDLE){            sprintf(state,"IDLE");         }else if(pool->token[i].state == TREAD_POOL_STATE_BUSY){            sprintf(state,"BUSY");         }else{            sprintf(state,"UNKNW");         }         if(pool->token[i].job){            fprintf(stdout, "%s/t %s/n",state,(pool->token[i].job)->desc);         }else{            fprintf(stdout, "%s/t N/A/n",state);         }      }      pthread_mutex_unlock(&(pool->token[i].lock));   }#ifdef _THREAD_POOL_JOB_LIST_   pthread_mutex_lock(&(pool->job_lock));   job = pool->job_head;   while(job){      fprintf(stdout,"     N/A/t N/A/t N/A/t STDBY/t %s/n",job->desc);      job = job->next;   }   pthread_mutex_unlock(&(pool->job_lock));#endif}static int thread_pool_find_free_token(thread_pool_t * pool){   int idx = -1, i;   if(pool == NULL)      return -1;   for(i=0; i < pool->size; i++ ){      pthread_mutex_lock(&(pool->token[i].lock));      if(pool->token[i].state == TREAD_POOL_STATE_NOTRUN){         idx = i;      }      pthread_mutex_unlock(&(pool->token[i].lock));      if(idx != -1)         break;   }   return idx;}static int thread_pool_find_serve_token(thread_pool_t * pool){   int idx = -1, i = 0;   if(pool == NULL)      return -1;   for(i=0; i<pool->size; i++ ){      pthread_mutex_lock(&(pool->token[i].lock));      if(pool->token[i].state == TREAD_POOL_STATE_IDLE){         idx = i;      }      pthread_mutex_unlock(&(pool->token[i].lock));      if(idx != -1)         break;   }   return idx;}#ifdef _THREAD_POOL_JOB_LIST_static thread_pool_job_t* pop_job(thread_pool_t * pool){   thread_pool_job_t* job_node = NULL;   if(pool){      pthread_mutex_lock(&(pool->job_lock));      job_node = pool->job_head;      if(job_node && job_node->next){         pool->job_head = job_node->next;         job_node->next = NULL;      }else{         pool->job_head = NULL;      }      pthread_mutex_unlock(&(pool->job_lock));   }   return job_node;}static void push_job(thread_pool_t * pool, thread_pool_job_t* job){   if(job == NULL)      return;   if(pool){      pthread_mutex_lock(&(pool->job_lock));      job->next = pool->job_head;      pool->job_head = job;      pthread_mutex_unlock(&(pool->job_lock));   }   return;}static void destroy_job_list(thread_pool_job_t* job_head){   thread_pool_job_t* job_node ;   while(job_head){      job_node = job_head;      job_head = job_head->next;      free(job_node);   }   job_head = NULL;   return;}#endif

 

3. thread_pool.def

 

#ifndef _THREAD_POOL_DEF_#define _THREAD_POOL_DEF_#ifndef _THREAD_POOL_JOB_LIST_#define _THREAD_POOL_JOB_LIST_#endif//#ifndef _DEBUG_VERSION_//#define _DEBUG_VERSION_//#endif#endif //end define _THREAD_POOL_DEF_

 

 

4.Makefile

 

obj=thread_pool.o
src=thread_pool.c
inc=thread_pool.h
def=thread_pool.def

target=$(obj)

.PHONY: all
.PHONY: clean
.PHONY: lib

all: $(target)
 @echo "Building Dolphin's Libaray"

$(obj): $(src) $(inc) $(def)
 gcc -g -c -fPIC $< -o $@

clean:
 rm -f *.o *.so *.a

lib: $(target)
 gcc -shared -fPIC -o libdol.so $(target)
 ar cr libdol.a $(target)

 

 

 

以上便是主要的源代码。

下面给出一个使用该线程池的例子: 

#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<signal.h>#include "thread_pool.h"int quit =0;void sig_handler(int sig_no){   quit = 1;}void call_back_func(void * arg ){   int p = (int)(void*)arg;   int i=0;   while(!quit){      //fprintf(stdout,"%-3d alive/n",p);      sleep(1);      break;   }}int main(int argc, char** argv){   thread_pool_t pool;   job_call_back_t call_back;   int i,rc;   char desc [64];   signal(SIGTERM, sig_handler);   signal(SIGINT, sig_handler);   rc = thread_pool_init(&pool, 5);   thread_pool_set_log("./test_tp.log");   if(rc != ETPOK){      fprintf(stderr,"thread_pool_init fail/n");      return 1;   }   sleep(2);   call_back = call_back_func;   for(i=0;i<10;i++){      sprintf(desc,"job %d",i);      //sleep(1);      rc = thread_pool_register_job(&pool, call_back, (void*)i, desc);      if(rc != TREAD_POOL_REG_OK){         fprintf(stderr,"regiser %d %s fail/n",i,desc);      }   }   while(!quit){      thread_pool_runtime(&pool);      sleep(1);   }   thread_pool_destroy(&pool);   fprintf(stdout,"program stoping!/n");   return 0;}

Makefile:

 

exe=test_tp
src=test_tp.c
obj=test_tp.o

.PHONY: all
.PHONY: clean

all: $(exe)
clean:
 rm -f $(exe) $(obj)

$(exe): $(obj)
 gcc -g $^ -o $@ -lpthread -L.. -ldol
$(obj): $(src)
 gcc -g -c $< -o $@ -I..


 

原创粉丝点击