池——线程池、进程池、内存池、连接池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YL970302/article/details/89553668

 为什么要使用线程池和进程池?

(1)动态创建子进程(子线程)是比较耗时的,这将导致较慢的客户响应

(2)动态创建的子进程(或子线程)通常只用来为一个客户服务(除非做特殊处理),这将导致系统上产生大量的细微进程(或线程)。进程(或线程)间的切换将消耗大量的CPU

(3)动态创建的子进程是当前进程的完整映像当前进程必须谨慎地管理其分配的文件描述符和堆内存等系统资源,否则子进程可能复制这些资源,从而使系统的可用资源急剧下降,进而影响服务器的性能

一、进程池

  进程池是由服务器预先创建的一组子进程,进程池中的所有子进程都运行着相同的代码,并且具有相同的属性

二、线程池

 线程池中的线程数量应该和CPU数量差不多

1、当有新的任务到来,主进程通过什么方式选择进程池中的某个子进程?

(1)最简单、最常用的算法是随机算法和轮流算法。更智能、更优秀的算法将使任务在各个工作进程中更均匀的分配,从而减轻服务器的整体压力

(2)主进程和所有子进程通过一个共享的工作队列来同步,子进程都睡眠在工作队列中,当有新的任务来临时,主进程将任务放在工作队列中,这就唤醒了正在等待的队列,不过只有一个子进程获得任务的接管权,它可以从工作队列中取出任务并执行,其他的子进程将继续睡眠在工作队列上

   在父子进程间预先建立好一条管道,当选择好子进程之后,通过这条管道来实现所有进程间的通信,即告诉子进程有新任务需要处理,并传递必要的数据。在父线程和子线程间传递数据简单是因为可以把这些数据定义为全局的,那么它们本身就是被所有线程共享的。

2、几种并发模式下,监听socket和连接socket是否都由主进程来同一管理?(否)

(1)半同步/半反应堆模式是由主进程统一管理这两种socket的。主进程接受新的连接得到连接socket,然后它需要将这个socket传给各个子进程

(2)高效的半同步/半异步模式(一个客户端上的所有任务始终是一由一个子进程来处理的 )以及领导者/追随者模式,则是由主进程管理所有的监听套接字,而各个子进程分别管理属于自己的连接套接字。子进程可以调用自己的accept来接受新的连接,这样父进程就无须向子进程传递socket,而只需要简单的通知一声“我检测到连接,你来接受它”。

3、一个客户的多次请求可以复用一个TCP连接,那么在设计进程池的时候,一个客户连接上的所有任务是否始终由一个子进程来处理?

(1)如果客户任务是无状态的,那么可以考虑使用不同的子进程为该客户的不同请求服务

(2)如果客户任务是存在上下文关系的,则最好是一直用同一个子进程来为之服务,否则实现起来比较麻烦,因为我们不得不在各个子进程之间传递上下文的数据

三、连接池

   连接池通常用于服务器或服务器机群的内部永久连接,在服务器中每个逻辑单元可能都需要频繁的访问本地的某个数据库。简单的做法是:逻辑单元每次需要访问数据库的时候,就向数据库程序发起连接,而访问完毕后释放连接。很显然,这种做法的效率太低。一种解决方案是使用连接池。连接池是服务器预先和数据库程序建立的一组连接的集合。当某个逻辑单元需要访问数据库的时候,它可以直接从连接池中取得一个连接的实体并使用。待完成数据库的访问之后,逻辑单元再将该连接返还给连接池

、内存池

    内存池通常用于socket的接收缓存和发送缓存。对于某些长度有限的客户请求,比如HTTP请求,预先分配一个大小足够(比如5000字节)的接收缓存区是很合理的。当客户请求的长度超过接收缓冲区的大小时,我们可以选择丢弃请求或者动态扩大接收缓冲区

猜你喜欢

转载自blog.csdn.net/YL970302/article/details/89553668