简化型高并发内存池整体框架设计中的 Central Cache 机制

时间:2024-11-22 13:14:07

补充

TLS--thread local storage线程局部存储

如果把thread cache存储在进程中,多线程共享,1.那就分不清这么多thread cache,分别和哪些线程对应 2.多线程在进程栈创建/访问threadcache 存在临界资源加锁问题。

解决:让每个thread cache存储在对应自己线程的局部存储中。

linux gcc / Windows vs下 TLS

https://zhuanlan.zhihu.com/p/142418922

分为静态/动态 TLS

这里用静态TLS,简单点

////ThreadCache.h
// TLS thread local storage
static _declspec(thread) ThreadCache* pTLSThreadCache = nullptr;
//static使 整个项目可以有多个pTLSThreadCache变量(只在自己的源文件中有效)
//若不加static,当前头文件若被多个源文件包含,会导致项目中有多个相同的全局变量,冲突出错(链接时,在调用/使用处准备寻找定义,发现有多个定义)


////ConcurrentAlloc.h
#pragma once

#include "Common.h"
#include "ThreadCache.h"

static void* ConcurrentAlloc(size_t size)
{
	// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象
	if (pTLSThreadCache == nullptr)
	{
		pTLSThreadCache = new ThreadCache;
	}

	cout << std::this_thread::get_id() << ":"<<pTLSThreadCache<<endl;

	return pTLSThreadCache->Allocate(size);
}

static void ConcurrentFree(void* ptr, size_t size)
{
	assert(pTLSThreadCache);

	pTLSThreadCache->Deallocate(ptr, size);
}


Central Cache

central cache也是一个哈希桶结构,他的哈希桶的映射关系跟thread cache是一样的。不同的是他的每个哈希桶位置挂是SpanList链表结构,不过每个映射桶下面的span中的大内存块被按映射关系切成了一个个小内存块对象挂在span的*链表中。

简化型高并发内存池整体框架设计中的 Central Cache 机制_加锁


申请内存:

  1. 当thread cache中没有内存时,就会批量向central cache申请一些内存对象,这里的批量获取对
    象的数量使用了类似网络tcp协议拥塞控制的慢开始算法;central cache也有一个哈希映射的
    spanlist,spanlist中挂着span,从span中取出对象给thread cache,这个过程是需要加锁的,不
    过这里使用的是一个桶锁(一个桶一个锁,只有同时访问同一个桶才会出现资源互斥问题),尽可能提高效率。
  2. central cache映射的spanlist中所有span的都没有内存以后,则需要向page cache申请一个新的
    span对象,拿到span以后将span管理的内存按大小切好作为*链表链接到一起。然后从span
    中取对象给thread cache。
  3. central cache的中挂的span中use_count记录分配了多少个对象出去,分配一个对象给thread
    cache,就++use_count

span内的空间是连续的,但各个span之间 空间不一定连续

central cache作用

均衡负载,承上启下

  • span是1/多个页的跨度,即包含1/多个页。一个span的大小不固定,具体根据场景来确定。
  • 一个span可能分给多个threadcache,用完了/没有一个span有合适的大小后,再向pagecache申请centercache。
  • 带头双向循环链表最高效,任意位置插入删除,时间复杂度都是O(1)。
  • 整个进程只有一个CenterCache,多个ThreadCache。此时CenterCache适合使用单例模式。
  • 不同位的机器物理内存中页个数不同(与地址个数有关)

简化型高并发内存池整体框架设计中的 Central Cache 机制_多线程_02