线程池
1.什么是线程池
线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
2.为什么用线程池
创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率
线程并发数量过多,抢占系统资源从而导致阻塞
我们知道线程能共享系统资源,如果同时执行的线程过多,就有可能导致系统资源不足而产生阻塞的情况
运用线程池能有效的控制线程最大并发数,避免以上的问题
对线程进行一些简单的管理比如:延时执行、定时循环执行的策略等
3.线程池采用生产者消费者模式
typedef struct
{
void *(*function) (void *);
void *arg;
} threadpool_task_t;
typedef struct threadpool_t {
pthread_mutex_t lock; /* 用于锁住本结构体 ,和条件变量一起使用 /
pthread_mutex_t thread_counter; / 记录忙状态线程个数的锁 – busy_thr_num /
pthread_cond_t queue_not_full; / 当任务队列满时,添加任务的线程阻塞,等待此条件变量 /
pthread_cond_t queue_not_empty; / 任务队列里不为空时,通知线程池中等待任务的线程 */
pthread_t *threads; /* 存放线程池中每个线程的tid。数组 */
pthread_t adjust_tid; /* 存管理线程tid */
threadpool_task_t *task_queue; /* 任务队列 */
int min_thr_num; /* 线程池最小线程数 */
int max_thr_num; /* 线程池最大线程数 */
int live_thr_num; /* 当前存活线程个数 */
int busy_thr_num; /* 忙状态线程个数 */
int wait_exit_thr_num; /* 要销毁的线程个数 */
int queue_front; /* task_queue队头下标 */
int queue_rear; /* task_queue队尾下标 */
int queue_size; /* task_queue队中实际任务数 */
int queue_max_size; /* task_queue队列可容纳任务数上限 */
int shutdown; /* 标志位,线程池使用状态,true或false */
} threadpool_t;
/* 线程池创建 /
threadpool_t threadpool_create(int min_thr_num, int max_thr_num, int queue_max_size);
/ 向任务队列中, 添加一个任务 /
int threadpool_add(threadpool_t pool, void (function)(void arg), void arg);
/ 销毁线程池 /
int threadpool_destroy(threadpool_t pool);
底层任务接口
voidthread_customer_job(void) //消费者从任务队列获取任务并执行
voidthread_manger_job(void)//管理者任务 周期检测完成线程扩容(满足自定义算法(通过thread_kill(tid,0)判断线程是否存活)死亡覆盖tid数组创建固定数量的线程)和缩减(满足自定义算法(通过判断线程闲忙(加标志位 0 1表示状态))杀死固定量的闲置的线程)
voidthread_user_job(void)//用户自定义任务
voidthread_error(void)//错误处理