c线程池有完整测试案例三

threadpool.c

#include"threadpool.h"


//线程池创建
int createThreadPool(ThreadPool*pool,int min,int max,int queueMaxNum)
{
    int iserror=0; //标记,用来接收错误标记
    do{    
       //线程池空间开辟
        if(pool == NULL)
        {
             //pool=(ThreadPool*)malloc(sizeof(ThreadPool));
            if(pool==NULL)
            {
                perror("pool create is error\n");
                iserror = -1;
                break;
            }            
        }
        memset(pool,0,sizeof(ThreadPool));  

        pool->min = min;
        pool->max = max;
        pool->busynum = 0;
        pool->exitnum= 0;
        pool->lifenum = pool->min;
        pool->queue_front=0;
        pool->queue_rear=0;
        pool->queue_size=0;
        pool->queue_max=queueMaxNum;

        //开辟任务队列空间
        pool->task=(Task*)malloc(sizeof(Task)*(pool->queue_max));
        if(pool->task==NULL)
        {
           perror("pool->task create is error\n");
           iserror = -2;
           break;
        }
        memset(pool->task,0,sizeof(Task)*(pool->queue_max));
        
        printf("xxxx %d\n",(sizeof(Task)*(pool->queue_max))/(sizeof(pool->task[0])));


        //开辟工作者线程空间
        pool->work_pthread=(pthread_t*)malloc(sizeof(pthread_t)*max);
        if(pool->work_pthread==NULL)
        {
           perror("pool->work create is error\n");
           iserror = -3;
           break;
        }
        memset(pool->work_pthread,0,sizeof(pthread_t)*max);
      
        //创建线程 
        for(int i=0;i<pool->min;i++)
        {
            pthread_create(&pool->work_pthread[i],NULL,workfun,(void*)pool);
        }


        //管理者线程
        pool->manger_work_pthread=(pthread_t*)malloc(sizeof(pthread_t));
       if( pool->manger_work_pthread==NULL)
        {
           perror("pool->manger_work create is error\n");
           iserror = -4;
           break;
        }
        memset(pool->manger_work_pthread,0,sizeof(pthread_t));
        pthread_create(pool->manger_work_pthread,NULL,mangerfun,(void*)pool);//创建管理者线程

        //线程锁和条件变量初始化
        if(
        pthread_mutex_init(&pool->mutexbusy,NULL) !=0 ||
        pthread_mutex_init(&pool->mutexpool,NULL)    !=0 ||
        pthread_cond_init(&pool->isfull,NULL)!=0 ||
        pthread_cond_init(&pool->isemety,NULL))
        {
            iserror=-5;
            break;
        }
 
        pool->showdownfalt = 0;//线程池销毁标记,0为正常,1为销毁

        return  0;
    }while(0);
  
    if(pool && pool->work_pthread)free(pool->work_pthread);
    if(pool && pool->manger_work_pthread)free(pool->manger_work_pthread);
    if(pool) free(pool);  
     
    return iserror;
}

//添加任务
int addTask(ThreadPool*pool,void*(*fun)(void*arg),void*arg)
{
    if(pool == NULL || fun == NULL || arg == NULL)
    {
        return -1;
    }

    pthread_mutex_lock(&pool->mutexpool);
    
    //当前任务数等于最大任务数,并且线程池正常运行
    while(pool->queue_size == pool->queue_max && pool->showdownfalt == 0)
    {
        pthread_cond_wait(&pool->isfull,&pool->mutexpool);
        //
    }
    if(pool->showdownfalt)//线程池需要销毁
    {
        pthread_mutex_unlock(&pool->mutexpool);
        return 0;
    }
 
   pool->task[pool->queue_front].fun=fun;
   pool->task[pool->queue_front].arg=arg;
   pool->queue_front=(pool->queue_front+1)%pool->queue_max;//保证存任务标记移动范围不会超过最大任务数量
   pool->queue_size++;
   pthread_cond_signal(&pool->isemety);
   pthread_mutex_unlock(&pool->mutexpool);
   return 0;

}//void addTask


//线程退出函数
void Mypthread_exit(ThreadPool*pool)
{
   if(pool == NULL)return;

   for(int i=0;i<pool->max;i++)
   {
       if(pool->work_pthread[i] == pthread_self())
       {
           pool->work_pthread[i]=0; //开辟的工作者线程空间中对应位置置0,表示空间可以再次使用
           break;
       }
   }
 
    printf("工作线程 %ld 退出\n",pthread_self());
    pthread_mutex_unlock(&pool->mutexpool);
    pthread_exit(NULL);

}

//工作者回调函数
void* workfun(void*arg)
{
    //线程分离,让系统自动回收资源
    pthread_detach(pthread_self());
    ThreadPool*pool=(ThreadPool*)arg;
    while(1)
    {
       pthread_mutex_lock(&pool->mutexpool);
       if(pool->queue_size==0 && pool->showdownfalt == 0)//任务数量为0,且线程池正常运行
       {
           pthread_cond_wait(&pool->isemety,&pool->mutexpool);

           if(pool->exitnum>0 && pool->showdownfalt == 0) //退出线程数量大于0
           {
              pool->exitnum--;
              if(pool->lifenum>pool->min)
              {
                  pool->lifenum--;
                  Mypthread_exit(pool);
              }
           }
       }

       if(pool->showdownfalt)//线程池正常运行
       {
            Mypthread_exit(pool);
       }
     
       Task *task = (Task*)malloc(sizeof(Task));
       memset(task,0,sizeof(Task));
       task->fun =pool->task[pool->queue_rear].fun;
       task->arg=pool->task[pool->queue_rear].arg;

       pool->queue_rear=(pool->queue_rear+1)%pool->queue_max;
       pool->queue_size--;

       pthread_cond_signal(&pool->isfull);
       pthread_mutex_unlock(&pool->mutexpool);
       
       printf("线程 %ld 开始工做.......\n",pthread_self());
       //锁忙变量
       pthread_mutex_lock(&pool->mutexbusy);
       pool->busynum++;
       pthread_mutex_unlock(&pool->mutexbusy);


        task->fun(task->arg);

        printf("线程 %ld 结束工作.......\n",pthread_self());
        task->fun=NULL;
        //开辟的空间回收        
        free(task->arg);
        task->arg=NULL;
        
        free(task);
        task=NULL;

      
       //解锁锁忙变量
       pthread_mutex_lock(&pool->mutexbusy);
       pool->busynum--;
       pthread_mutex_unlock(&pool->mutexbusy);

    }
 

}


//管理者回调函数
void* mangerfun(void*arg)
{
    ThreadPool*pool=(ThreadPool*)arg;
    while(1)
    {
        pthread_mutex_lock(&pool->mutexpool);
        //获取忙线程数
        int busyNum = pool->busynum;
        pthread_mutex_unlock(&pool->mutexpool);

        pthread_mutex_lock(&pool->mutexpool);
        //获取存活的线程数
        int lifeNum = pool->lifenum;
        pthread_mutex_unlock(&pool->mutexpool);
        
        if(pool->showdownfalt == 1)
        {
            printf("管理者线程退出。。。\n");
            pthread_exit(NULL);
        }


        //增加线程,增加条件,如果当前任务数大于当前
        pthread_mutex_lock(&pool->mutexpool);

        if(pool->queue_size>pool->lifenum && pool->lifenum < pool->max)
        {
                int  pthread_addnum=0; //临时变量
                for(int i=0;i<pool->max;i++)
                 {
                
                    //线程空间中,找到未使用的空间
                    if(pool->work_pthread[i]==0 && pool->showdownfalt == 0)
                    {
                        
                        pthread_create(&pool->work_pthread[i],NULL,workfun,(void*)pool);
                        printf("工作者线程 %ld 被管理者创建\n",pool->work_pthread[i]);
                        pthread_addnum++;
                        pool->lifenum++; //存活线程数量++
                        if(pthread_addnum== PTHREAD_ADDNUM || pool->lifenum == pool->max)
                        {
                            break;
                        }
 
                    }
                    
                }
        }
       
        pthread_mutex_unlock(&pool->mutexpool);

        //减少线程()
        //工作的线程数量*2小于或者的线程, 并且存活的线程数量大于最小线程数
        if(pool->busynum*2 < pool->lifenum && pool->lifenum > pool->min+PTHREAD_DESTORYNUM)
        {
            pthread_mutex_lock(&pool->mutexpool);
            pool->exitnum=PTHREAD_DESTORYNUM;
            pthread_mutex_unlock(&pool->mutexpool);
            for(int i=0;i<PTHREAD_DESTORYNUM;i++)
            {
                pthread_cond_signal(&pool->isemety);
            }
            // pthread_mutex_unlock(&pool->mutexpool);
        }
    }
}

int destroyPthreadPool(ThreadPool*pool)
{
    if(pool == NULL)
       return -1;

    pool->showdownfalt = 1;  //线程池销毁标记为1,确认销毁
    pthread_join(*(pool->manger_work_pthread),NULL);
    for(int i=0;i<pool->lifenum;i++)
    {
       pthread_cond_signal(&pool->isemety);
    }

    //工作者线程工作模式设置成了分离,等待几秒,给工作者线程运行时间
    sleep(3);

    //释放开辟的任务队列空间、工作者线程空间、管理者线程空间、线程池空间
    

    if(pool && pool->work_pthread)free(pool->work_pthread);
    if(pool && pool->manger_work_pthread)free(pool->manger_work_pthread);
    if(pool) free(pool);  
    

    //条件变量和互斥锁销毁
    if(pthread_mutex_destroy(&pool->mutexpool)     !=0 ||
       pthread_mutex_destroy(&pool->mutexpool)     !=0 ||
       pthread_cond_destroy(&pool->isemety)        !=0||
       pthread_cond_destroy(&pool->isfull)         !=0)
      {
        perror("互斥锁和条件变量销毁失败");
        return -2;
      }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值