[转载]hazard pointer
hazard pointer
转载自: http://hi.baidu.com/rodimus/item/f6539cc179894f2f47d5c0ef
这是用于解决多线程并发下内存的回收,一块内存被释放之后,并不能直接交回给操作系统,因为可能有别的线程正在读这个数据。那什么时候交还给操作系统呢?不 同的应用不一样。等的时间太短,可能会读到已经释放的内存,会CORE; 时间太长,内存的利用率会下降。以前做检索系统的时候,有些很山寨的方法解决这些问题。
通用的解决方案有:
(1)加读写锁,应用的时候要注意锁的粒度,锁的粒度太大,并发度低,锁粒太细,需要很多锁,锁本身的资源开销很大。这种情况下一般假设读写是均匀分布在各个内存单元的,但是很多应用里读写是比较集中的。
(2)引用计数,给每个内存节点加一个计数,要用的时候加1,用完减1,减到0就表示不用了,这个的内存开销会比较大。
(3)就是要介绍的hazard pointer:
观察到,读线程虽然需要读很多数据,但是在特定时刻,它需要读的内存单元是很少的,比如检索系统读倒排,其实它就只需要读链表上某个节点,不需要读整个链表,有点飞矢不动的感觉。所以别的线程删除数据的时候,只需要看一下所有线程正在读的内存,如果该内存没线程在读,就可以删除了。具体实现的时候,每个线程开一个大小为K的数组,用于存储它正在读的内存地址,每个线程也有一个链表记录它需要删除的内容。简单来说是这样,但是要解决的问题还是很多的:
(a)扩展性,线程数N可能很大,线程在某一瞬间需要同时读的内存K可能很多,这样N*K的话,数量会很大,会使得遍历的性能很差。所以可以考虑用一个拉链把所有线程的hazard pointer串起来
(b)性能,删除的时候需要遍历所有的hazard pointer,确认没有线程正在读这块内存,反复遍历会很耗时间。所以把需要删除的内存先缓存起来,再一次遍历hazard pointer,批量回收内存
(c)多写,这个需要上层自己解决,利用CAS之类的原语重复检验,如果在获得原始数据,修改数据之间,有别的线程已经完成操作,则需要把工作重复做一遍
(d)读写并发,考虑两种情况,一是读线程已经读完了,但是写线程还认为它在读,这种情况是没有问题的,只是降低了回收的速度:
一是写线程认为没有线程在读,准备回收的时候,有线程在读。这需要上层自己解决,读线程,如果在获得数据、把数据加为hazard pointer之间,有删除操作发生,则需要重新读取。写线程,在把内存放进待删除拉链之前,修改相应指针,让后来的读线程读不到数据,让已经读到但是没加进hazard pointer的线程能获得通知。
从论文上看到的实测数据,这一方案比读方法(1)(2)都要优,但是论文的数据里并没有讨论hazard pointer的数量,应该是默认一个线程一个hazard pointer测的。
[转载]hazard pointer的更多相关文章
- 实现无锁的栈与队列(5):Hazard Pointer
两年多以前随手写了点与 lock free 相关的笔记:1,2,3,4,质量都不是很高其实(读者见谅),但两年来陆陆续续竟也有些阅读量了(可见剑走偏锋的技巧是多容易吸引眼球).笔记当中在解决内存释放和 ...
- 风险指针(Hazard Pointer) 内存空间共享模型
WiredTiger是一种高性能的开源存储引擎,现已在MongoDB中作为内模式应用.WiredTiger支持行存储.列存储两种存储模式,采用LSM Tree方式进行索引记录 WiredTiger支持 ...
- lock free数据结构内存回收技术-hazard pointer
lock free数据结构一般来说拥有比基于lock实现的数据结构更高的性能,但是其实现比基于lock的实现更为复杂,需要处理的难题包括预防ABA问题,内存如何重用和回收等.通常,最简单最有效的处理A ...
- [转载]锁无关的数据结构与Hazard指针——操纵有限的资源
Lock-Free Data Structures with Hazard Pointers 锁无关的数据结构与Hazard指针----操纵有限的资源 By Andrei Alexandrescu a ...
- wiredtiger - hazard pointers
http://www.drdobbs.com/lock-free-data-structures-with-hazard-po/184401890 memory deallocation lock- ...
- 【转载】MySQL · 性能优化· InnoDB buffer pool flush策略漫谈
背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数个内存块加上一组控制结构体对象组成.内存块的个数取决于buffer pool inst ...
- C++11原子操作与无锁编程(转)
不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...
- MongoDB新存储引擎WiredTiger实现(事务篇)
导语:计算机硬件在飞速发展,数据规模在急速膨胀,但是数据库仍然使用是十年以前的架构体系,WiredTiger 尝试打破这一切,充分利用多核与大内存时代,开发一种真正满足未来大数据管理所需的数据库.本文 ...
- MySQL · 性能优化· InnoDB buffer pool flush策略漫谈
MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...
随机推荐
- 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法
题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...
- 【JavaScript&jQuery】单选框radio,复选框checkbox,下拉选择框select
HTML: <!DOCTYPE html> <html> <head> <title></title> <meta charset=& ...
- P2812 校园网络【[USACO]Network of Schools加强版】
题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是由于他们脑力劳动过多导致全身无力身体被♂掏♂空,他们来找你帮助他们. 题目描述 共 ...
- 对于最近的一些日常总结by520(17.10.18)
---天天考试,各种题型都有,学到了很多新的知识,也发现了自己的许多不足---1.首先,自己的搜索需要加强,特别是广搜,10.18的T1裸广搜没有做对.2.数学的思维和一些逻辑问题需要加强,然后就是要 ...
- Count the string HDU - 3336
题意: 求一个字符串的每个前缀在这个字符串中出现次数的加和 解析: 默默的骂一句...傻xkmp..博主心里气愤... 拓展kmp就好多了... 因为拓展kmp每匹配一次 就相当于这些前缀出现了一 ...
- YOLO v1之总结篇(linux+windows)
YOLO出自2016 CVPR You Only Look Once:Unified, Real-Time Object Detection,也是一个非常值得学习的框架,不得不说facebook的技术 ...
- Virtual Box虚拟机下CentOS网络设置
VirtualBox中有4中网络连接方式: a. NAT 网络地址转换模式(Network Address Translation)b. Bridge ...
- Spring MVC POJO传参方式
有两POJO类 Address.java package com.proc; public class Address { private String province; private Strin ...
- 多线程中join方法的含义
1.作用:调用这个方法的时候,主进程会在这里停住,等待该线程进行完毕再继续往下执行. 如:不使用join的情况: <?php class Join extends Thread { public ...
- php中foreach使用引用的陷阱
有时候我们为了在循环过程中改变数组项的值,在foreach的时候变量入口可以加个&符合, 表示,循环过程中使用数组中原来的值,而不是一个复制的值,如 foreach ($array as &a ...