线程池使用的场景为处理大量短暂任务。计算密集型任务 线程池阈值与cpu核心数持平。io密集型任务,又有IO任务经常有阻塞,线程池阈值要大于cpu核心数。
condition.h
#include<pthread.h>
#include<time.h>
struct condition_t
{
pthread_mutex_t mutex;
pthread_cond_t cond;
};
void condition_init(condition_t *ready);
void condition_destroy(condition_t *ready);
void condition_lock(condition_t *ready);
void condition_unlock(condition_t *ready);
void condition_wait(condition_t *ready);
void condition_signal(condition_t *ready);
void condition_broadcast(condition_t *ready);
int condition_timedwait(condition_t *ready,timespec *tv);
condition.c
#include"condition.h"
woid condition_init(condition_t *ready)
{
int status;
if (status=pthread_mutex_init(&ready->mutex,NULL))
{
return status;
}
if(status =pthread_cond_init(&ready->cond,NULL))
{
return status;
}
return status;
}
void condition_destroy(condition_t *ready)
{
pthread_mutex_destroy(&ready->mutex);
pthread_cond_destroy(&ready->cond);
}
void condition_lock(condition_t *ready)
{
pthread_mutex_lock(&ready->mutex);
}
void condition_unlock(condition_t *ready)
{
pthread_mutex_unlock(&ready->mutex);
}
void condition_wait(condition_t *ready)
{
pthread_cond_wait(&ready->cond,&ready->mutex);
}
void condition_signal(condition_t *ready)
{
pthread_cond_signal(&ready->cond);
}
void condition_broadcast(condition_t *ready)
{
pthread_cond_broadcast(&ready->cond);
}
int condition_timedwait(condition_t *ready,timespec *tv)
{
return pthread_cond_timedwait(&ready->cond,&ready->mutex,tv);
}
threadpool.h
#include "condition.h"
struct task_t
{
void * (*run)(void * arg);
void * arg;
task_t * next;
};
struct threadpool_t
{
condition_t ready;
task_t *first;
task_t *last;
int idle;
int counter;
int threshold;
int quit;
};
void threadpool_init(threadpool_t * pool,int num);
void threadpool_addtask(threadpool_t *pool,void *(*run)(void * arg),void * arg);
void threadpool_destroy(threadpool_t * pool);
threadpool.c
#include"threadpool.h"
#include<stdlib.h>
#include<iostream>
#include<time.h>
#include<errno.h>
#include<stdio.h>
using namespace std;
//线程池初始化
void threadpool_init(threadpool_t * pool,int num)
{
cout <<"threadpool init ..." <<endl;
condition_init(&pool->ready);
pool->first=pool->last=NULL;
pool->idle =0;
pool->counter=0;
pool->threshold=num;
pool->quit=0;
}
void * threadroute(void * arg)
{
threadpool_t *pool = (threadpool_t *)arg;
cout <<"thread "<<pthread_self() <<" is starting ..." <<endl;
while(true)
{
pool->idle++;
int timeout =0;
condition_lock(&pool->ready);
while(pool->first==NULL&&!pool->quit)
{
timespec *tv;
clock_gettime(CLOCK_REALTIME,tv);
tv->tv_sec+=2;
int status = condition_timedwait(&pool->ready,tv);
if(status==ETIMEDOUT)
{
timeout=1;
break;
}
}
pool->idle--;
if(pool->first!=NULL)
{
task_t *task=pool->first;
pool->first= task->next;
condition_unlock(&pool->ready);
task->run(task->arg);
free(task);
condition_lock(&pool->ready);
}
if(pool->quit&&pool->first==NULL)
{
pool->counter--;
condition_unlock(&pool->ready);
break;
}
if(timeout)
{
pool->counter--;
condition_unlock(&pool->ready);
break;
}
condition_unlock(&pool->ready);
}
cout <<"threadpool exit ..." <<endl;
}
//添加线程池任务
void threadpool_addtask(threadpool_t *pool,void *(*run)(void * arg),void * arg)
{
//获取任务节点
task_t *task=(task_t *)malloc(sizeof(task_t));
task->run = run;
task->arg = arg;
task->next=NULL;
//添加任务到线程池 操作线程池需要枷锁
condition_lock(&pool->ready);
if(pool->first==NULL)
{
pool->first=task;
}
else
{
pool->last->next=task;
}
pool->last=task;
if(pool->idle)
{
cout <<"22222222222222222" <<endl;
condition_signal(&pool->ready);
}
else if (pool->counter<pool->threshold)
{
pthread_t pid;
pthread_create(&pid,NULL,threadroute,pool);
pool->counter++;
}
condition_unlock(&pool->ready);
}
void threadpool_destroy(threadpool_t * pool)
{
if (pool->quit==1)
{
return ;
}
condition_lock(&pool->ready);
pool->quit=1;
if(pool->counter >0)
{
if(pool->idle>0)
{
condition_broadcast(&pool->ready);
}
while(pool->counter!=0)
{
condition_wait(&pool->ready);
}
}
condition_unlock(&pool->ready);
}
maic.c
#include<stdio.h>
#include"threadpool.h"
#include<unistd.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
void * test(void * arg)
{
cout <<"task"<< *(int *)arg<<" is working on thread "<<pthread_self() <<endl;
free(arg);
sleep(1);
return NULL;
}
int main()
{
threadpool_t pool;
threadpool_init(&pool,3);
for(int i=0;i<10;i++)
{
int *tmp =(int *)malloc(sizeof(int));
*tmp=i;
threadpool_addtask(&pool,test,tmp);
}
threadpool_destroy(&pool);
return 0;
}
makefile:
all:main.o condition.o threadpool.o
g++ main.o condition.o threadpool.o -o all -lpthread
main.o:main.c
g++ -c main.c -o main.o
threadpool.o:threadpool.c
g++ -c threadpool.c -o threadpool.o
condition.o:condition.c
g++ -c condition.c -o condition.o
.PHONY : clean
clean :
rm -rf *.o