#include
#include
#include
#include
#include
struct job
{
void *(*func)(void *arg);
void *arg;
struct job *next;
};
struct threadpool
{
int thread_num;//已开启的线程数量
pthread_t *pthread_ids;//保存线程池中线程id
struct job *head;//任务队列的头指针
struct job *tail;//任务队列的尾指针
int queue_max_num;//任务队列的最大数
int queue_cur_num;//任务队列已有多少任务
pthread_mutex_t mutex;
pthread_cond_t queue_empty;//任务队列为空的条件
pthread_cond_t queue_not_empty;//任务队列不为空的条件
pthread_cond_t queue_not_full;//任务队列不为满的条件
};
//线程函数
void *threadpool_function( void * arg)
{
struct threadpool *pool = (struct threadpool *) arg ;
struct job *pjob = NULL;
while(1)
{
pthread_mutex_lock( &(pool->mutex) );
while(pool->queue_cur_num == 0) //任务队列是否为空
{
pthread_cond_wait( &(pool->queue_not_empty), &(pool->mutex) );
}
pjob = pool->head;
pool->queue_cur_num --;
if(pool->queue_cur_num != pool->queue_max_num)
{
pthread_cond_broadcast( &(pool->queue_not_empty) );
}
if ( pool->queue_cur_num==0 )
{
pool->head = pool->tail = NULL ;
pthread_cond_broadcast( &(pool->queue_empty) );
}
else
{
pool->head = pool->head->next ;
}
pthread_mutex_unlock( &(pool->mutex) );
(*(pjob->func))(pjob->arg);
free(pjob);
pjob = NULL ;
}
}
//线程池初始化
struct threadpool *threadpool_init( int thread_num,int queue_max_num)
{
struct threadpool *pool=( struct threadpool * )malloc( sizeof(struct threadpool) );
//malloc
//int thread_num = 20;
//int queue_max_num = 100;
pool->thread_num = thread_num ;
pool->queue_max_num = queue_max_num;
pool->queue_cur_num = 0;
pool ->head = NULL;
pool->tail = NULL;
pthread_mutex_init( &(pool->mutex) ,NULL );
pthread_cond_init( &(pool->queue_empty), NULL );
pthread_cond_init( &(pool->queue_not_empty) , NULL );
pthread_cond_init( &(pool->queue_not_full) , NULL );
pool->pthread_ids = (pthread_t *) malloc( sizeof(pthread_t) * thread_num );
//malloc
for ( int i = 0; i < pool->thread_num ; i++)
{
pthread_create( &(pool->pthread_ids[i ]) , NULL , threadpool_function , (void *)pool );
}
return pool;
}
//添加任务函数
void threadpool_add_job(struct threadpool *pool,void *func(void *) , void * arg )
{
pthread_mutex_lock(&(pool->mutex));
while(pool->queue_cur_num == pool->queue_max_num)
{
pthread_cond_wait( &(pool->queue_not_full), &(pool->mutex) );
}
struct job *pjob = (struct job *)malloc ( sizeof(struct job));
//malloc
pjob->func = func ;
pjob->arg = arg;
if(NULL == pool->head)
{
pool->head = pool->tail =pjob;
pthread_cond_broadcast(&(pool->queue_not_empty) );
}
else
{
pool->tail ->next = pjob;
pool->tail = pjob;
}
pool->queue_cur_num ++;
pthread_mutex_unlock( &(pool->mutex) );
}
void * work ( void * arg )
{
char * p =(char *)arg;
printf("hello world %s\n",p);
printf("welcome to china %s\n",p);
sleep(1);
}
//资源回收
void threadpool_destroy (struct threadpool *pool )
{
pthread_mutex_lock(&(pool->mutex) );
while( pool->queue_cur_num != 0 )
{
pthread_cond_wait( &(pool->queue_empty) , &(pool->mutex) );
}
pthread_mutex_unlock( &(pool->mutex) );
pthread_cond_broadcast(&(pool->queue_empty) );
pthread_cond_broadcast(&(pool->queue_not_empty) );
pthread_cond_broadcast(&(pool->queue_not_full) );
free(pool->pthread_ids);
for( int i = 0 ; i< pool->thread_num ; i++)
{
pthread_cancel(pool->pthread_ids[i] );
pthread_join(pool->pthread_ids[i] ,NULL );
}
struct job *temp;
while(pool->head !=NULL )
{
temp = pool->head;
pool->head = temp->next;
free(temp);
}
free(pool);
pthread_mutex_destroy(&(pool->mutex));
pthread_cond_destroy(&(pool->queue_empty));
pthread_cond_destroy(&(pool->queue_not_empty));
pthread_cond_destroy(&(pool->queue_not_full));
}
int main()
{
struct threadpool * pool = threadpool_init( 10,100 );
threadpool_add_job( pool , work , "1" );
threadpool_add_job( pool , work , "2" );
threadpool_add_job( pool , work , "3" );
threadpool_add_job( pool , work , "4" );
threadpool_add_job( pool , work , "5" );
threadpool_add_job( pool , work , "6" );
threadpool_add_job( pool , work , "7" );
threadpool_add_job( pool , work , "8" );
threadpool_add_job( pool , work , "9" );
threadpool_add_job( pool , work , "10" );
threadpool_add_job( pool , work , "11" );
threadpool_add_job( pool , work , "22" );
threadpool_add_job( pool , work , "33" );
threadpool_add_job( pool , work , "44" );
threadpool_add_job( pool , work , "55" );
threadpool_add_job( pool , work , "66" );
threadpool_add_job( pool , work , "77" );
threadpool_add_job( pool , work , "88" );
threadpool_add_job( pool , work , "99" );
threadpool_add_job( pool , work , "100" );
sleep(50);
threadpool_destroy(pool );
return 0;
}
root@jsetc-virtual-machine:/0504# ./xcc
hello world 2
welcome to china 2
hello world 10
welcome to china 10
hello world 4
welcome to china 4
hello world 3
welcome to china 3
hello world 5
welcome to china 5
hello world 1
welcome to china 1
hello world 6
welcome to china 6
hello world 7
welcome to china 7
hello world 9
welcome to china 9
hello world 8
welcome to china 8
hello world 11
welcome to china 11
hello world 22
welcome to china 22
hello world 44
welcome to china 44
hello world 55
hello world 66
welcome to china 66
welcome to china 55
hello world 33
welcome to china 33
hello world 77
welcome to china 77
hello world 88
welcome to china 88
hello world 99
welcome to china 99
hello world 100
welcome to china 100
^C
要是一个应用需要频繁的创建和销毁线程,任务执行的时间又比较短的话,就轮到线程池出场,但是线程创建和销毁的时间相比任务执行时间少很多的话,就没有必要用线程池了。