我们正在开发一个基于C / S的网络应用程序,我们发现有太多的锁添加到std :: map,服务器的性能变差了。
我想知道是否可以实现无锁地图,如果有,怎么样?那里有开源代码吗?
编辑: 实际上我们使用std :: map来存储套接字信息,我们根据套接字文件描述进行了封装,以包含一些其他必要的信息,如ip地址,端口,套接字类型,tcp或udp等。
总结一下,我们有一张全球地图说它是
map<int fileDescriptor, socketInfor*> SocketsMap,
然后用于发送数据的每个线程都需要访问SocketsMap,并且他们必须在从SocketsMap读取或写入SocketsMap之前添加互斥锁,因此整个应用程序的并发级别会因为添加如此多的锁而大大减少到SocketsMap。
为了避免并发级问题,我们有两个解决方案:1。分别存储每个socketInfor * 2.使用某种无锁映射。
我想找到某种无锁映射,因为此解决方案所需的代码更改远远少于解决方案1。
答案 0 :(得分:15)
实际上有一种方法,虽然我没有自己实现,但有一篇关于来自着名C ++专家Andrei Alexandrescu的lock free map using hazard pointers的论文。
答案 1 :(得分:3)
是的,我已经使用&#34;拆分有序列表&#34;在C ++中实现了Lock-Free Unordered Map(docs)。概念。它是一个自动扩展容器,支持64位CAS上的数百万个元素而无需ABA问题。在性能方面,它是beast(参见第5页)。它有extensively tested,有数百万随机操作。
答案 2 :(得分:2)
HashMap会适合吗?看看Intel Threading Building Blocks,他们有一个有趣的并发地图。我不确定它是否无锁,但希望你对良好的多线程性能感兴趣,尤其是在无锁性方面。您也可以查看CityHash lib
编辑:
实际上TBB的哈希映射不是无锁的
答案 3 :(得分:2)
如果您使用C ++ 11,可以查看facebook/folly
的AtomicHashMap答案 4 :(得分:1)
您可以使用 optimistic design或transactional memory 来实施地图。
如果两个操作同时解决映射的可能性和一个正在改变它的结构的可能性相对较小,这种方法尤其有效 - 并且您不希望每次都锁定开销。
但是,有时会发生冲突,你必须以某种方式产生(通常是回滚到最后一个稳定状态并重试操作)。
如果您的硬件支持足够好的原子操作 - 这可以通过Compare And Swap (CAS)轻松完成 - 您可以单独更改引用(无论何时更改地图,您都可以处理地图的副本,而不是原始的,只有当你提交时才将它设置为主要的。
答案 5 :(得分:1)
我很惊讶没人提到它,但Click Cliff实现了一个无等待的hashmap in Java,我相信它可以移植到C ++,