模型原理分析:
线程池的关键优势在于它减少了每次任务执行时创建和销毁线程的开销
线程池的组成主要分为 3 个部分,这三部分配合工作就可以得到一个完整的线程池:
1. 任务队列,存储需要处理的任务,由工作的线程来处理这些任务
通过线程池提供的 API 函数,将一个待处理的任务(客户端提交)添加到任务队列,或者从任务队列中删除,已处理的任务会从任务队列中删除;线程池的使用者,也就是调用线程池函数往任务队列中添加任务的线程即生产者线程
2. 工作的线程(任务队列任务的消费者) ,N个
线程池中维护了一定数量的工作线程,他们的作用是是不停的读任务队列,从里边取出任务并处理;工作的线程相当于是任务队列的消费者角色;如果任务队列为空,工作的线程将会被阻塞 (使用条件变量 / 信号量阻塞);如果阻塞之后有了新的任务,由生产者将阻塞解除,工作线程开始工作
3. 管理者线程(不处理任务队列中的任务),1个
它的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测。当任务过多的时候,可以适当的创建一些新的工作线程。当任务过少的时候,可以适当的销毁一些工作的线程
线程池的工作原理的基本步骤:
1. 初始化:
在程序开始时或者当需要使用多线程时,创建一定数量的线程,这些线程通常会在一个阻塞状态下等待任务的分配。这些线程被创建并加入到池中,形成一个可用线程的集合。
2. 等待任务:
线程池中的线程通常会等待任务队列,直到有任务提交给线程池执行。
3. 任务的分配:
当一个外部线程(线程池的客户端)提交一个任务时,任务会被添加到任务队列中。线程池中的某个线程(通常是队列中的第一个线程)会从队列中取出任务并执行。
4. 执行任务:
被分配任务的线程会执行具体的任务,在任务执行期间,该线程不会对其他任务可用。
5. 任务完成:
一旦任务完成,线程会报告任务完成,并且变得再次可用于执行队列中的下一个任务,如果任务执行过程中产生了异常,异常会被捕获并根据具体的线程池实现处理。
6. 线程的循环使用:
完成任务的线程会返回到线程池中,处于等待状态,直到再次被分配新的任务
7. 关闭线程池:
当不再需要线程池时,可以关闭线程池。这通常涉及到发送中断信号给所有等待的线程,停止它们等待新的任务。有些线程池会等待所有正在执行的任务完成后再终止线程。一旦线程池关闭,它就不能再接收新的任务了。
线程池模块分析:
1. main();
创建线程池。
向线程池中添加任务。 借助回调处理任务。
销毁线程池。
2. pthreadpool_create();
创建线程池结构体 指针。
初始化线程池结构体 { N 个成员变量 }
创建 N 个任务线程。
创建 1 个管理者线程。
失败时,销毁开辟的所有空间。(释放)
3. threadpool_thread()
进入子线程回调函数。
接收参数 void *arg --> pool 结构体
加锁 -->lock --> 整个结构体锁
判断条件变量 --> wait -------------------170
4. adjust_thread()
循环 10 s 执行一次。<