Linux环境下C语言实现线程池

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


struct Job_poll{      //任务池
  void*(*callback_function)(void* arg);
  void* arg;
  struct Job_poll* next;
};
struct thread_poll{
  int num;             //第一次初始化的线程个数
  int max_num;         //线程池中最大的线程数
  
  int job_num;         //记录工作中的线程数
  
  pthread_t*  threads;         //记录线程id

  struct Job_poll* jobpoll_tail;       //任务池尾
  struct Job_poll* jobpoll_head;       //任务池头

  pthread_mutex_t  mutex;                 //互斥量

  pthread_cond_t   threadpoll_empty;      //当线程池为空时条件变量
  pthread_cond_t   threadpoll_full;       //当线程池满时条件变量
  pthread_cond_t   jobpoll_empty;         //当任务池为空时
  pthread_cond_t   jobpoll_full;          //当任务池满时

  int threadpoll_close;                   //记录线程池是否关闭
  int jobpoll_close;                      //记录任务池是否关闭
};
//初始化线程池
struct thread_poll* threadpoll_init(int num,int max_num);
//添加任务到任务池中
int threadpoll_add_job(struct thread_poll* poll,void* (*callback_function) (void* arg),void* arg);
//任务线程,任务池里减少
int threadpoll_function(struct thread_poll* poll);
//销毁线程池
int destory_thread_poll(struct thread_poll* poll);
//工作函数
void* work(void* arg);
///-----------------------开始main
int main(){
  struct thread_poll* poll = threadpoll_init(10,15);
  if(NULL == poll){
    printf("线程池开辟失败!\n");
    return -1;
  }
  //开始添加任务到任务池中
  threadpoll_add_job(poll,work,"任务1");
  threadpoll_add_job(poll,work,"任务2");
  threadpoll_add_job(poll,work,"任务3");
  threadpoll_add_job(poll,work,"任务4");
  threadpoll_add_job(poll,work,"任务5");
  threadpoll_add_job(poll,work,"任务6");
  printf("线程池结束!\n");
  sleep(60);
  return 0;
}
//------------------------开始公司定义
//初始化线程池
struct thread_poll* threadpoll_init(int num,int max_num){
  //分配空间
  struct thread_poll* poll = (struct thread_poll*)malloc(sizeof(struct thread_poll));
  poll->num = num;
  poll->max_num = max_num;

  poll->job_num = 0;     //工作线程数量初始化为零
  poll->threads = (pthread_t *)malloc( sizeof(pthread_t)*max_num);        //分配内存空间

  poll->jobpoll_head = (struct Job_poll*)malloc(sizeof(struct Job_poll));
  poll->jobpoll_head->next = NULL;
  poll->jobpoll_tail = NULL;

  pthread_mutex_init(&(poll->mutex),NULL);
  pthread_cond_init(&(poll->threadpoll_empty),NULL);
  pthread_cond_init(&(poll->threadpoll_full),NULL);
  pthread_cond_init(&(poll->jobpoll_empty),NULL);
  pthread_cond_init(&(poll->jobpoll_full),NULL);

  poll->threadpoll_close = 0;
  poll->jobpoll_close = 0;

  //养线程池里的线程
  for(int i=0;i<num;i++){
      pthread_create(&(poll->threads[i]),NULL,threadpoll_function,poll);
  }

  return poll;
} //init

//添加任务到任务池中
int threadpoll_add_job(struct thread_poll* poll,void* (*callback_function) (void* arg),void* arg){
      //防御性判断
  if(poll == NULL){
    printf("poll is NULL !\n");
    return -1;
  }
  if(callback_function == NULL){
    printf("callback_funciton is NULL\n");
    return -1;
  }
  if(arg == NULL){
    printf("arg is NULL\n");
    return -1;
  }
  //------------
  pthread_mutex_lock(&(poll->mutex));
  //开始判断线程池的工作数量是否是线程池中的最大数量
  while(1){
      if( (poll->job_num == poll->max_num) &&
          !(poll->threadpoll_close || poll->jobpoll_close)){       //这里意味着线程池线程最大负荷
        pthread_cond_wait(&(poll->threadpoll_full),&(poll->mutex));       //就意味着线程池和任务池满了,就阻塞在这里
      }else{
        break;
      }
  }  //while
  if((poll->threadpoll_close || poll->jobpoll_close )){
      printf("线程池/任务池关闭:结束程序\n");
      destory_thread_poll(poll);
  }
  //开始添加任务到任务池里
  struct Job_poll* job = (struct Job_poll*)malloc(sizeof(struct Job_poll));
  job->arg = arg;
  job->callback_function = callback_function;
  //头插法
  job->next = poll->jobpoll_head->next;
  poll->jobpoll_head->next = job;    //将新来的任务添加到任务池中
  if(job->next == NULL){
    //如果以前为空时,那么有任务线程是阻塞在这里的
    pthread_cond_broadcast(&(poll->jobpoll_empty));       //唤醒阻塞在任务池为空这里的线程
  }
  poll->job_num++;

  pthread_mutex_unlock(&(poll->mutex));
  return 0;     //成功返回0
}
//任务线程,任务池里减少
int  threadpoll_function(struct thread_poll* poll){
  //struct thread_poll* poll = (struct thread_poll*)arg;
  if(NULL == poll){
    printf("未传入线程池对象,无法执行任务!\n");
    return -1;
  }
  while(1){    //一个工作线程循环的解决掉任务池中的任务
  //  printf("开始运行\n");
    pthread_mutex_lock(&(poll->mutex));
    while(1){
      if((poll->job_num) == 0 &&
          !(poll->threadpoll_close || poll->jobpoll_close)){
              pthread_cond_wait(&(poll->jobpoll_empty),&(poll->mutex));
      }else{
        break;
      }
    }  //while
    
    if(poll->jobpoll_close && poll->threadpoll_close){
      printf("threadpoll_function 里,线程池/任务池关闭!\n");
      return -1;
    }

    //开始将任务读出来
    struct Job_poll* job = poll->jobpoll_head->next;
    if(NULL == job){
        printf("取出的任务节点是空值!\n");
        return -1;
    }
    //将任务从任务池中删除
    poll->jobpoll_head->next = job->next;
    poll->job_num--;
    pthread_cond_broadcast(&(poll->threadpoll_full));               //唤醒一个线程池满情况下的阻塞线程。
    //开始运行任务函数
    (*(job->callback_function))(job->arg);
    //开始销毁数据
    free(job);
    job = NULL;
    pthread_mutex_unlock(&(poll->mutex));
  } //while
  return 0;
}
//销毁线程池
int destory_thread_poll(struct thread_poll* poll){
  if(NULL == poll){
    printf("销毁线程时,线程池对象为空!\n");
    return -1;
  }
  free(poll->jobpoll_head);
  free(poll->threads);
  pthread_mutex_destroy(&(poll->mutex));
  pthread_cond_destroy(&(poll->threadpoll_empty));
  pthread_cond_destroy(&(poll->threadpoll_full));
  pthread_cond_destroy(&(poll->jobpoll_empty));
  pthread_cond_destroy(&(poll->jobpoll_full));
  return 0;
}
//工作函数
void* work(void* arg){
  char* temp = (char*)arg;
  printf("这里是工作函数,%s\n",temp);
  sleep(1);
  return NULL;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值