线程池
线程池维护一组线程,线程可以是预先分配好的,也可以在线程池运行过程中进行分配。
为什么使用线程池
如果对每个请求/会话/连接都创建一条线程进行服务,在请求/会话/连接频繁的时候,会频繁的进行线程的创建和销毁。同时存在大量的线程会占用过多的 OS 资源 (线程表和相关操作需要的资源),频繁的创建和销毁线程会浪费 CPU 资源。
使用线程池将线程限制在指定的数量,从而限制线程的存在对 OS 资源的使用,同时也无需大量的创建和销毁线程。
线程池模型
线程池模型分为 Half-sync/Half-async model 和 Leader/follower model。
半同步/半异步模型
在此模型中,一个 listener
异步地接受请求并将它们缓存到队列
中;一组 worker
同步地从队列中取出请求进行处理。
当队列通知有新的数据到来时,线程池中一个空闲的 worker 接受新的数据并进行处理,如果没有空闲的 worker,当有 worker 完成上一个请求时,则会处理该请求。
半同步/半异步的模型有下列优点:
- 能应对突然增多的客户端请求,当没有空闲的 worker 时,请求被缓存于队列中。
- 同步操作和异步操作解耦,同步操作间相互独立。
半同步/半异步的模型有下列缺点:
- 异步线程与同步线程间进行同步和上下文切换需要的开销。在多处理器机器上,还要承担数据拷贝和缓存一致性的开销。
- 不能将请求信息保存在栈上或线程特定存储中,因为请求是在不同的 worker 线程处理的。
领导者/跟随者模型
该模型中,线程池管理一组线程,其中有一个 leader,其他的线程全都是 follower。当有请求到达时,leader 负责接受该请求,并且选择一个线程池中的 follower 成为新的 leader,自己则原地处理该请求,当请求处理完成时,线程以 follower 身份返回线程池。
领导者/跟随者模型的优点:
- 没有线程间上下文切换;
- 允许在栈上或线程指定存储中保存请求数据。
领导者/跟随者模型的缺点:
- 应对激增的请求数量时表现的不好;
- 更难以实现。
线程池注意事项
避免大请求数据的拷贝。
合适的线程数量。