优化多线程安全的内存池

内存池的实现和管理(一)

内存池的实现和管理(二)

前面两篇博客主要介绍了内存池的原理和实现,这篇博客主要是介绍如何优化多线程安全的内存池

 

内存池的实现和管理(二)中内存池的实现代码存在的问题

  虽然在内存申请和释放的时候,使用lock_guard()实现了多线程安全的内存池,但是频繁的加锁和解锁带来了不必要的上下文切换开销,导致整个内存池的使用性能下降许多(主要体现在单次申请释放/释放内存需要的时间上升),和直接向系统申请内存的效率差许多

 

也就是说,虽然可以减少内存碎片的产生,但是并不能提高申请内存的效率

 

优化方案一:

  在多线程情况下,申请内存时加锁是必然的,每次申请向内存池申请内存块的时候都要即时加锁,但是释放内存块的时候我们可以延时释放,做一个定时任务去遍历内存池中管理内存块的链表,加锁一次释放多个内存块,这样就减少了释放内存块时的加锁次数

 

  在内存池中释放内存块有两个步骤:

  1、把内存使用标记从已使用状态改为未使用

  2、第一个未使用内存块指针的移动

 

  释放内存时只要求第2步需要互斥进行,所以我们在释放的时候先修改标记状态(不加锁),执行一次定时任务,遍历管理内存块的链表,修改第一个未分配内存块的指针(加锁)

 

优化方案二:

  产生冲突的根本原因是因为多个线程共用一个内存池,我们可以让每个线程都拥有一个内存池,这样内存块的申请和释放都在本线程内进行,自然不用加锁

  但是这样在多线程的 情况下使用不方便,内存利用率低下,并且管理内存池很繁琐

 

  换一个思路,依然时多个线程共用一个内存池,但是我们给不同的线程安排不同的内存使用区域,这样即时不加锁也可以实现内存池的互斥使用

  具体做法是可以给num个内存块进行编号,假设有n个线程,每个线程可使用的内存块个数t=num/n,根据线程id确定该线程使用的内存区域为[t*(id-1),t*id);id的取值范围为[1,n]

 

 

参考博客https://blog.csdn.net/luzubodfgs/article/details/65632609

 

posted @ 2020-12-15 15:54  知道了呀~  阅读(1284)  评论(0编辑  收藏  举报