SEBR处理多线程场景下的一般性GC问题。
为了验证它的有效性,我根据java-1.8版之后的ConcurrentHashMap改成了一个C++的版本(好吧,真实情况是一遍设计SEBR一遍写出这个ConcurrentHashMap)。
由于ConcurrentHashMap是为了Read-mostly设计的,所以这个ConcurrentHashMap相对于之前的版本最大的区别在于:
- 当某个bucket长度达到8,这个bucket就会二叉树化。
- 当长度小于6又会从二叉树转化回链表。
而facebook开源的folly看起来就是参考Java1.7的版本改了改出了一个C++的版本,之前写过它的实现采用了hazard pointers的方式。
所以新的ConcurrentHashMap算法是怎么样的,这一方面已有很多说明源码的资料。
用C++造一个并发数据结构比Java难很多,哪怕是直接照搬Java的实现也很难,最主要的是一般性GC问题,因为没有一个机制去安全地删除已经不需要的数据,而有了SEBR 我就能灵活准确地解决这个问题了。
concurrent_hash_map.hppgithub.com是C++的一个并发哈希表实现,它不是无锁的,它提供了insert/erase/find三个接口。find接口有两种返回值的实现,一种(find)是将value复制回来,另一种(find_reference)不复制,直接访问哈希表中的value,这种情况下需要考虑value被删除的可能,而通过sebr可以准确地实现这一点。
而使用sebr的方式是在通过retire调用,确保此后的线程再也拿不到这个地址。从而确保当前已经拿到该地址的线程们退出操作之后,便可以物理回收这块内存。
g++ -std=c++17 -pthread -Wall -W -g -O3 -o test test_concurrent_hash_map.cpp
./test 2 100000 8
test_concurrent_hash_mapgithub.com