内存池、进程池、线程池——池基本概念

池的概念

  对于服务器端的软件开发种,我们为了解决多个客户端同时访问服务器即并发访问的问题,我们引入了多进程和多线程机制,通过主进程(主线程)创建其子进程(子线程)完成客户端的请求,但是这样的机制也带来了一些需要考虑的问题:

  • 进程(线程)间的切换消耗了较大的CPU时间,影响到提供服务的效率;
  • 由于系统限制,可创建的进程(线程)数量有限;
  • 在多进程中,父进程创建子进程采用的是复制当前进程的完整映像,若没对其进行处理或限制则会使系统的资源空间下降,影响服务器性能。

  为此我们通过Pool(池)的结构来提高应用程序的速度,改善效率和降低系统资源开销,池顾名思义就是资源的一个集合,它通常在服务器启动时建立并初始化,即静态资源分配,当服务器接到客户端的请求时,可从池中直接获取需要的资源不需要动态分配。其思想是以空间换取时间,因为池相当于服务器管理系统资源的应用设施,当客户端发送请求时,服务器端会从池中申请所需要的资源;处理完客户端后将相关的资源放回池中,不与要调用系统调用对内核频繁访问,这样就解决了上述的几个缺点。

内存池

  在我们调用newmalloc动态分配内存函数时会由用户定义所分配大小不等,位置不定的资源,若多次申请则会陈胜大量的内存碎片使得程序性能降低。
  而内存池(Memory Pool)就是在使用内存前先申请一定数量,大小相等的内存块做备用,当有申请请求时,就会从内存池中分出一部分内存块供使用,若内存块不够则可申请新的内存,程序释放内存时没有是放到操作系统种而是还给了内存池,这样就使得内存分配效率提高。

进程池&&线程池

  进程池和线程池的思想类似,我们以进程池为例介绍(同样适用线程池):
  进程池由服务器预先创建一组子进程,通常数目在3~10之间,线程池中的线程数量和CPU数量差不多。
  进程池种所有子进程运行相同的代码,具有相同属性(优先级、PGID)等。
  当心的任务到来时主进程会通过选择进程池中的某个子进程来执行,相比创建子进程,选择存在的子进程来执行的代价小很多,通常有两种方法来选择子进程执行任务:

  1. 主进程会通过算法来选择子进程,最简单常用的就是随机算法和Round Robin(轮流算法)。
  2. 主进程和所有子进程会通过共享工作队列进行同步,子进程在工作队列上睡眠,当有新的任务时,主进程将任务添加到工作队列,唤醒睡眠等待的子进程,只有一个子进程会执行该任务。

 选择好子进程,主进程会使用通知机制告知目标子进程有任务处理,并传递所需数据,最简单的方式就是在父子进程间建立好管道,实现进程间的通信。在父子线程种可设置数据为全局变量,择其本身为线程共享数据。
在这里插入图片描述
线程池的应用

  1. 需要大量的线程完成任务且任务时间较短。例如WEB服务器完成网页请求的任务,任务小数量大。而Telnet连接请求就不适合线程池,因为Telnet会话时间比线程创建时间长很多。
  2. 对性能要求苛刻的应用,例如要求服务器迅速响应客户的请求。
  3. 接受突发性大量请求,但不至于服务器产生大量线程的应用。

 进程池&&线程池的引用减少了创建和释放子进程、子线程从而提高了服务器的性能和效率。

  巨人的肩膀:Linux–线程池与进程池及线程池的简单实现

猜你喜欢

转载自blog.csdn.net/weixin_42647166/article/details/105667977