打印

【转】池化技术”漫谈 - 线程池,内存池,连接池……

[复制链接]
535|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
风萧寒|  楼主 | 2017-1-9 12:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

原文来自:http://blog.csdn.NET/magictong/article/details/3143947

池化技术 - 简单点来说,就是提前保存大量的资源,以备不时之需,O(∩_∩)O,对于线程,内存,Oracle的连接对象等等,这些都是资源,程序中当你创建一个线程或者在堆上申请一块内存时,都涉及到很多系统调用,也是非常消耗CPU的,如果你的程序需要很多类似的工作线程或者需要频繁的申请释放小块内存,如果没有在这方面进行优化,那很有可能这部分代码将会成为影响你整个程序性能的瓶颈。池化技术主要有线程池,内存池,连接池,对象池等等,对象池就是提前创建很多对象,将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用,连接池比较典型的有oracle的连接池,了解不深。

下面主要谈谈线程池和内存池,因为这两种技术的通用性和实用性也是比较强的,描述语言C++,其实线程池的话用什么实现都可以。


先来谈谈线程池技术,线程池的框架早就有先辈给我们想好了,也就不用我们去冥思苦想了,我们要做的就是把先辈的想法发现即可。

其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。可能你也许会问:为什么要搞得这么麻烦,如果每当客户端有新的请求时,我就创建一个新的线程不就完了?这也许是个不错的方法,因为它能使得你编写代码相对容易一些,但你却忽略了一个重要的问题?性能!尤其是对于服务器程序尤为重要,服务器程序会先初始化很多线程在那里等待,当有客户连接时,就激活其中的一个线程来处理客户请求,对于不支持动态增加的线程池,如果没有等待线程,客户就必学等待,而对于能动态增加线程的线程池,则可以像线程池中新加一个线程。

下面是一个用c++实现的线程池,支持动态增减线程数量:

代码的详细注释我就不写了,想弄懂原理的还是好好研究下再使用,我不保证里面没有BUG。


再来看看内存池的原理,我下面的参考资料里面有几篇**讲得不错,想了解原理的可以去看看。

如何更好的管理在应用程序中内存的使用,同时提高内存使用的效率,这是值得每一个开发人员深思的问题。内存池(Memory pool)提供了一种比较可行的解决方案。首先是创建内存池。这个过程的主要任务是预先分配足够大的内存,形成一个初步的“内存池”。分配内存,也就是用户请求内存时,会返回内存池中一块空闲的内存,并将其标志置为已使用,当然具体细节和方法有很多。释放内存时,不是真正地调用free或是delete的过程,而是把内存放回内存池的过程。在把内存放入内存池的同时,要把标志位置为空闲。最后在应用程序结束时,要把内存池销毁。这里主要做的工作就是把内存池中的每一块内存释放。

使用内存池的好处:

1、减少了内存碎片的产生。这个可以从创建内存池的过程中看出。我们在创建内存池时,分配的都是一块块比较整的内存块,这样可以减少内存碎片的产生。

2、提高了内存的使用效率。这个可以从分配内存和释放内存的过程中看出。每次的分配与释放并不是去调用系统提供的函数或是操作符去操作实际的内存,而是在复用内存池中的内存。

缺点就是很有可能会造成内存的浪费,原因也很明显,开始分配了一大块内存,不是全部都用得到的。

针对内存池,这里有两个实现,头一个很简单,用到了STL的队列来管理内存池指针,而且如果分配的内存没有显示的归还给内存池的话,即使内存池销毁的时候,这块内存也不会被销毁,就会有内存泄露,当然这个程序还可以改进,另外一个程序是根据《C++应用程序性能优化》中提到的一种方法来实现的。




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

134

帖子

3

粉丝