当前位置: 首页 > article >正文

threadcache实现细节(二)

目录

  • TLS(thread local storage)(解决锁的问题)
    • Linux下的TLS
    • Windows下的TLS
      • 声明_declspec(thread)
        • static void* ConcurrentAlloc(size_t size)申请线程对象
        • void ThreadCache::Deallocate(void* ptr, size_t size)归还空间给thread cache
        • static void ConcurrentFree(void* ptr, size_t size)归还线程对象
      • 测试代码
        • 创建多线程环境
        • 创建线程

感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录
🤠🤠🤠 高并发内存池项目

TLS(thread local storage)(解决锁的问题)

在之前有说过高并发内存池中每个线程都有自己独享的thread cache,而thread cache在之前的文章中也说到过是哈希桶结构,现在的问题是我们如何让每个线程都独享自己的thread cache呢

在多线程中,在一个进程里可能有多个线程,多个线程共享进程地址的空间,每个线程有自己独立的空间 栈等等,每个线程也共享全局段 代码段等等
比如下图中有三个thread cache,我们怎么确定他对应的线程能够独享呢,或者说谁是谁的thread cache,什么时候创建thread cache呢,如果是哪个线程申请的时候再创建的话就会涉及到加锁的问题,因为可能两个线程同时申请
在这里插入图片描述
具体要解决锁问题就需要用TLS
一个线程修改的内存内容,对所有线程都生效。这是一个优点也是一个缺点。说它是优点,线程的数据交换变得非常快捷。说它是缺点,一个线程死掉了,其它线程也性命不保; 多个线程访问共享数据,需要昂贵的同步开销,也容易造成同步相关的BUG

如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量(被称为static memory local to a thread 线程局部静态变量),就需要新的机制来实现。这就是TLS

TLS的功能简单的来说就是这个线程里面的东西其他线程不可以访问

Linux下的TLS

Thread Local Storage(线程局部存储)TLS

Windows下的TLS

声明_declspec(thread)

static _declspec(thread)ThreadCache* pTLSThreadCache = nullptr
当我们声明后每个线程都有他自己的pTLSThreadCache h,这里用static修饰是为了避免在其他文件冲突

static void* ConcurrentAlloc(size_t size)申请线程对象

这里用static修饰是为了避免在多个文件时链接属性冲突问题

static void* ConcurrentAlloc(size_t size)
{
	if (pTLSThreadCache == nullptr)
	{
		pTLSThreadCache = new ThreadCache;
	}
	cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;
	return pTLSThreadCache->Allocate(size);
}
void ThreadCache::Deallocate(void* ptr, size_t size)归还空间给thread cache
void ThreadCache::Deallocate(void* ptr, size_t size)
{
	assert(ptr);
	assert(size <= MAX_BYTES);
	size_t index = SizeClass::Index(size);//计算桶的位置
	_freeLists[index].Push(ptr);//插入桶
}

因为thread cache是哈希桶结构,在归还的时候要知道是在哪个桶,所以要用之前的已经写好的函数Index(size)计算桶的位置,然后再用_freeLists[index].Push(ptr),将空间偷插进自由链表中

static void ConcurrentFree(void* ptr, size_t size)归还线程对象
static void ConcurrentFree(void* ptr, size_t size)
{
	assert(pTLSThreadCache);
	pTLSThreadCache->Deallocate(ptr, size);
}

测试代码

因为要测试多线程的情况,所以要包含C++11的一个头文件thread用来创建多线程场景

创建多线程环境
void Alloc1()
{
	for (size_t i = 0; i < 5; ++i)
	{
		void* ptr = ConcurrentAlloc(6);
	}
}
void Alloc2()
{
	for (size_t i = 0; i < 5; ++i)
	{
		void* ptr = ConcurrentAlloc(7);
	}
}

这里的ConcurrentAlloc(6)是调用ConcurrentAlloc,一次调6字节

创建线程
void TLSTest()
{
	std::thread t1(Alloc1);
	t1.join();
	std::thread t2(Alloc2);
	t2.join();
}

t1和t2是thread线程对象,这两个线程执行Alloc1和Alloc2,t1.john表示t1加入主线程
每个线程创建是并不是代表他立刻就有thread cache,而是调用相关的接口ConcurrentAlloc等


http://www.kler.cn/a/428560.html

相关文章:

  • flume系列之:flume落cos
  • 数据结构-二叉树
  • 国产编辑器EverEdit - 列编辑模式
  • 2025/1/21 学习Vue的第四天
  • 高频词汇背诵 Day1
  • MFC 使用 32位带Alpha通道的位图
  • Linux-V4L2摄像头应用编程
  • 安卓调试环境搭建
  • RTCMultiConnection 跨域问题解决
  • js循环导出多个word表格文档
  • OD B卷【恢复数字序列】
  • TCP客户端服务器端通信(线程池版)
  • 【机器学习】基于SVM、逻辑回归和CNN的手写数字识别:性能对比与应用分析
  • (七)腾讯cloudstudio+Stable-Diffusion-webui AI绘画教程-安装Stable-Diffusion-WebUI
  • Vue3组件通信(父传子,子传父,跨组件通信)
  • 21届秋/校招面经
  • xLSTM 阅读笔记
  • 日本IT|企业需要什么样的技术?
  • 处理后端返回的时间格式问题
  • MySQL -- CURD(下)
  • AUTOSAR CP复杂驱动程序(Complex Driver,CDD)的设计与集成指南导读
  • 动态规划子序列问题系列一>最长递增子序列
  • 用Python开发“迷你井字棋”小游戏
  • find命令深度详解
  • 计算机视觉:学习指南
  • 【python 批量将PPT中各种东西保存为图片 没有水印】