[转载]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通常由数 ...
随机推荐
- BZOJ4719 NOIP2016天天爱跑步(线段树合并)
线段树合并的话这个noip最难题就是个裸题了. 注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里. #include<iostream> #inc ...
- [JSOI2009]游戏 二分图博弈
题面 题面 题解 二分图博弈的模板题,只要会二分图博弈就可以做了,可以当做板子打. 根据二分图博弈,如果一个点x在某种方案中不属于最大匹配,那么这是一个先手必败点. 因为对方先手,因此我们就是要找这样 ...
- 常州day7
Task1 蛤布斯有一个序列,初始为空.它依次将 1-n 插入序列,其中 i 插到当前第 ai 个数的右边 (ai=0 表示插到序列最左边).它希望你帮 它求出最终序列. 对于 100%的数据,n&l ...
- Middle of Linked List
Find the middle node of a linked list. Example Given 1->2->3, return the node with value 2. Gi ...
- (转)ARC指南 - strong、weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...
- char* & 与 char*
原文 char*& 为指针引用,通常需要更改指针本身并返回时才这样用. char *&是指针引用char *是指针当用指针引用作为形参的时候,改变形参的指针,同时实参的指针也改变了.当 ...
- 解决html设置height:100%无效的问题
通常我们需要让自己的网页内容能够更好的适配各种屏幕大小,会采用height:100%,但是我们发现问题出来了,height:100%无效,其实解决办法很简单 解决:你只需要在css处添加上html, ...
- git安装和简单配置
http://pan.baidu.com/share/link?shareid=4291215660&uk=219947478 直接贴网盘的地址了
- Codeforces 221 C. Little Elephant and Problem
C. Little Elephant and Problem time limit per test 2 seconds memory limit per test 256 megabytes inp ...
- 数字配对(bzoj 4514)
Description 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对 ...