#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;
}
Linux环境下C语言实现线程池
最新推荐文章于 2023-09-07 13:40:50 发布