linux下C实现线程池的源代码

ThreadPool
ThreadPool头文件:
/**
 * threadpool.h
 *
 * This file declares the functionality associated with
 * your implementation of a threadpool.
 * 线程池的实现
 
*/


#ifndef __threadpool_h__
#define  __threadpool_h__

#ifdef __cplusplus
extern   " C "   {
#endif

// maximum number of threads allowed in a pool
//最大线程数在池中
#define MAXT_IN_POOL 200

// You must hide the internal details of the threadpool
// structure from callers, thus declare threadpool of type "void".
// In threadpool.c, you will use type conversion to coerce
// variables of type "threadpool" back and forth to a
// richer, internal type.  (See threadpool.c for details.)
//为了向使用者隐藏线程池的内部结构细节,将threadpool声明为void*
//在threadpool.c中可以用类型转换转换回来,细节请看threadpool.c

typedef 
void *threadpool;

// "dispatch_fn" declares a typed function pointer.  A
// variable of type "dispatch_fn" points to a function
// with the following signature:
// 
//     void dispatch_function(void *arg);
//dispatch_fn定义函数指针

typedef 
void (*dispatch_fn)(void *);

/**
 * create_threadpool creates a fixed-sized thread
 * pool.  If the function succeeds, it returns a (non-NULL)
 * "threadpool", else it returns NULL.
 
*/

//创建固定大小的线程池,如果创建成功,函数返回非空值,否则返回空值
threadpool create_threadpool(int num_threads_in_pool);


/**
 * dispatch sends a thread off to do some work.  If
 * all threads in the pool are busy, dispatch will
 * block until a thread becomes free and is dispatched.
 * 
 * Once a thread is dispatched, this function returns
 * immediately.
 * 
 * The dispatched thread calls into the function
 * "dispatch_to_here" with argument "arg".
 
*/

//分配一个线程完成请求,如果池中所有线程都非空闲,调度程序阻塞直到有线程空闲并马上调度
//一旦一个线程被调度,函数马上返回
//这个线程调用函数dispathch_to_here,arg作为函数参数
int dispatch_threadpool(threadpool from_me, dispatch_fn dispatch_to_here,
          
void *arg);

/**
 * destroy_threadpool kills the threadpool, causing
 * all threads in it to commit suicide, and then
 * frees all the memory associated with the threadpool.
 
*/

//销毁线程池,使池中所有线程自杀,之后释放所有相关内存
void destroy_threadpool(threadpool destroyme);

#ifdef __cplusplus
}

#endif

#endif
线程池实现代码文件:
/**
 * threadpool.c
 *
 * This file will contain your implementation of a threadpool.
 * 此文件包含线路池的具体实现
 
*/


#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< unistd.h >
#include 
< pthread.h >
#include 
< string .h >

#include 
" threadpool.h "

typedef 
struct  _thread_st  {
    pthread_t id;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    dispatch_fn fn;
    
void *arg;
    threadpool parent;
}
 _thread;

//  _threadpool is the internal threadpool structure that is
//  cast to type "threadpool" before it given out to callers
//  _threadpool是内部线程池结构,转换成类型“threadpool”在提交给使用者之前
typedef  struct  _threadpool_st  {
    
// you should fill in this structure with whatever you need
    pthread_mutex_t tp_mutex;
    pthread_cond_t tp_idle;
    pthread_cond_t tp_full;
    pthread_cond_t tp_empty;
    _thread 
** tp_list;
    
int tp_index;
    
int tp_max_index;
    
int tp_stop;

    
int tp_total;
}
 _threadpool;

threadpool create_threadpool(
int  num_threads_in_pool)
{
    _threadpool 
*pool;

    
// sanity check the argument
        
//参数检查
    if ((num_threads_in_pool <= 0|| (num_threads_in_pool > MAXT_IN_POOL))
        
return NULL;

    pool 
= (_threadpool *) malloc(sizeof(_threadpool));
    
if (pool == NULL) {
        fprintf(stderr, 
"Out of memory creating a new threadpool! ");
        
return NULL;
    }


    
// add your code here to initialize the newly created threadpool
    pthread_mutex_init( &pool->tp_mutex, NULL );
    pthread_cond_init( 
&pool->tp_idle, NULL );
    pthread_cond_init( 
&pool->tp_full, NULL );
    pthread_cond_init( 
&pool->tp_empty, NULL );
    pool
->tp_max_index = num_threads_in_pool;
    pool
->tp_index = 0;
    pool
->tp_stop = 0;
    pool
->tp_total = 0;
    pool
->tp_list = ( _thread ** )malloc( sizeofvoid * ) * MAXT_IN_POOL );
    memset( pool
->tp_list, 0sizeofvoid * ) * MAXT_IN_POOL );

    
return (threadpool) pool;
}


int  save_thread( _threadpool  *  pool, _thread  *  thread )
{
    
int ret = -1;

    pthread_mutex_lock( 
&pool->tp_mutex );

    
if( pool->tp_index < pool->tp_max_index ) {
        pool
->tp_list[ pool->tp_index ] = thread;
        pool
->tp_index++;
        ret 
= 0;

        pthread_cond_signal( 
&pool->tp_idle );

        
if( pool->tp_index >= pool->tp_total ) {
            pthread_cond_signal( 
&pool->tp_full );
        }

    }


    pthread_mutex_unlock( 
&pool->tp_mutex );

    
return ret;
}


void   *  wrapper_fn(  void   *  arg )
{
    _thread 
* thread = (_thread*)arg;
    _threadpool 
* pool = (_threadpool*)thread->parent;

    
for( ; 0 == ((_threadpool*)thread->parent)->tp_stop; ) {
        thread
->fn( thread->arg );

        pthread_mutex_lock( 
&thread->mutex );
        
if0 == save_thread( thread->parent, thread ) ) {
            pthread_cond_wait( 
&thread->cond, &thread->mutex );
            pthread_mutex_unlock( 
&thread->mutex );
        }
 else {
            pthread_mutex_unlock( 
&thread->mutex );
            pthread_cond_destroy( 
&thread->cond );
            pthread_mutex_destroy( 
&thread->mutex );

            free( thread );
            
break;
        }

    }


    pthread_mutex_lock( 
&pool->tp_mutex );
    pool
->tp_total--;
    
if( pool->tp_total <= 0 ) pthread_cond_signal( &pool->tp_empty );
    pthread_mutex_unlock( 
&pool->tp_mutex );

    
return NULL;
}


int  dispatch_threadpool(threadpool from_me, dispatch_fn dispatch_to_here,  void   * arg)
{
    
int ret = 0;

    _threadpool 
*pool = (_threadpool *) from_me;
    pthread_attr_t attr;
    _thread 
* thread = NULL;

    
// add your code here to dispatch a thread
    pthread_mutex_lock( &pool->tp_mutex );

    
if( pool->tp_index <= 0 && pool->tp_total >= pool->tp_max_index ) {
        pthread_cond_wait( 
&pool->tp_idle, &pool->tp_mutex );
    }


    
if( pool->tp_index <= 0 ) {
        _thread 
* thread = ( _thread * )malloc( sizeof( _thread ) );
        thread
->id = 0;
        pthread_mutex_init( 
&thread->mutex, NULL );
        pthread_cond_init( 
&thread->cond, NULL );
        thread
->fn = dispatch_to_here;
        thread
->arg = arg;
        thread
->parent = pool;

        pthread_attr_init( 
&attr );
        pthread_attr_setdetachstate( 
&attr,PTHREAD_CREATE_DETACHED );

        
if0 == pthread_create( &thread->id, &attr, wrapper_fn, thread ) ) {
            pool
->tp_total++;
            printf( 
"create thread#%ld ", thread->id );
        }
 else {
            ret 
= -1;
            printf( 
"cannot create thread " );
            pthread_mutex_destroy( 
&thread->mutex );
            pthread_cond_destroy( 
&thread->cond );
            free( thread );
        }

    }
 else {
        pool
->tp_index--;
        thread 
= pool->tp_list[ pool->tp_index ];
        pool
->tp_list[ pool->tp_index ] = NULL;

        thread
->fn = dispatch_to_here;
        thread
->arg = arg;
        thread
->parent = pool;

        pthread_mutex_lock( 
&thread->mutex );
        pthread_cond_signal( 
&thread->cond ) ;
        pthread_mutex_unlock ( 
&thread->mutex );
    }


    pthread_mutex_unlock( 
&pool->tp_mutex );

    
return ret;
}


void  destroy_threadpool(threadpool destroyme)
{
    _threadpool 
*pool = (_threadpool *) destroyme;

    
// add your code here to kill a threadpool
    int i = 0;

    pthread_mutex_lock( 
&pool->tp_mutex );

    
if( pool->tp_index < pool->tp_total ) {
        printf( 
"waiting for %d thread(s) to finish ", pool->tp_total - pool->tp_index );
        pthread_cond_wait( 
&pool->tp_full, &pool->tp_mutex );
    }


    pool
->tp_stop = 1;

    
for( i = 0; i < pool->tp_index; i++ ) {
        _thread 
* thread = pool->tp_list[ i ];

        pthread_mutex_lock( 
&thread->mutex );
        pthread_cond_signal( 
&thread->cond ) ;
        pthread_mutex_unlock ( 
&thread->mutex );
    }


    
if( pool->tp_total > 0 ) {
        printf( 
"waiting for %d thread(s) to exit ", pool->tp_total );
        pthread_cond_wait( 
&pool->tp_empty, &pool->tp_mutex );
    }


    
for( i = 0; i < pool->tp_index; i++ ) {
        free( pool
->tp_list[ i ] );
        pool
->tp_list[ i ] = NULL;
    }


    pthread_mutex_unlock( 
&pool->tp_mutex );

    pool
->tp_index = 0;

    pthread_mutex_destroy( 
&pool->tp_mutex );
    pthread_cond_destroy( 
&pool->tp_idle );
    pthread_cond_destroy( 
&pool->tp_full );
    pthread_cond_destroy( 
&pool->tp_empty );

    free( pool
->tp_list );
    free( pool );
}

下面是一个线程池测试程序:
/**
 * threadpool_test.c, copyright 2001 Steve Gribble
 *
 * Just a regression test for the threadpool code.
 * 仅为以上线程池代码的一个测试
 
*/


#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< unistd.h >
#include 
< pthread.h >
#include 
< errno.h >
#include 
< stdarg.h >
#include 
" threadpool.h "

extern   int  errno;

void  mylog( FILE  *  fp,  const    char    * format,   /*args*/  ...)
{
    va_list ltVaList;
    va_start( ltVaList, format );
    vprintf( format, ltVaList );
    va_end( ltVaList );

    fflush( stdout );
}


void  dispatch_threadpool_to_me( void   * arg)  {
  
int seconds = (int) arg;

  fprintf(stdout, 
"  in dispatch_threadpool %d ", seconds);
  fprintf(stdout, 
"  thread#%ld ", pthread_self() );
  sleep(seconds);
  fprintf(stdout, 
"  done dispatch_threadpool %d ", seconds);
}


int  main( int  argc,  char   ** argv)  {
  threadpool tp;

  tp 
= create_threadpool(2);

  fprintf(stdout, 
"**main** dispatch_threadpool 3 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *3);
  fprintf(stdout, 
"**main** dispatch_threadpool 6 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *6);
  fprintf(stdout, 
"**main** dispatch_threadpool 7 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *7);

  fprintf(stdout, 
"**main** done first ");
  sleep(
20);
  fprintf(stdout, 
" ");

  fprintf(stdout, 
"**main** dispatch_threadpool 3 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *3);
  fprintf(stdout, 
"**main** dispatch_threadpool 6 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *6);
  fprintf(stdout, 
"**main** dispatch_threadpool 7 ");
  dispatch_threadpool(tp, dispatch_threadpool_to_me, (
void *7);

  fprintf(stdout, 
"**main done second ");

  destroy_threadpool( tp );

  sleep(
20);
  exit(
-1);
}

GCC 测试成功。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值