C ++中的无锁数据结构=只使用原子和内存排序?

时间:2014-01-12 02:54:29

标签: c++ multithreading c++11 concurrency atomic

我曾经看过“无锁数据结构”一词,并认为“ooooo必须非常复杂”。但是,我一直在阅读“C ++并发操作”,它似乎写了一个无锁数据结构你所做的就是停止使用互斥锁/锁并用原子代码替换它们(以及可能的内存排序障碍)。

所以我的问题是 - 我在这里遗漏了什么?由于C ++ 11,它真的更简单吗?写一个无锁数据结构只是用原子操作替换锁吗?

4 个答案:

答案 0 :(得分:5)

Ooooo但 非常复杂。

如果您没有看到互斥锁和原子访问之间的区别,那么您查看并行处理的方式就会出现问题,并且您编写的代码很快就会出现问题。

很可能它会比同等的阻止版本运行得慢,如果你(或者说你的同事)真的不走运,它会喷出偶尔出现的不一致数据并随机崩溃。

更有可能的是,它会将实时约束传播到应用程序的大部分内容,迫使你的同事浪费相当多的时间来应对他们的任意要求,而且他们的软件很乐意在没有这些要求的情况下生活,并诉诸于各种迷信将代码混淆为提交的良好做法。

哦,好吧,只要模板人和等待的人都有他们的小乐趣......


并行处理,无论是阻塞还是假设无需等待,本身就是资源消耗,实现复杂且成本高昂。设计一个能够从非平凡的并行处理中获得真正优势的软件架构是专家的工作。

相反,良好的软件设计应该将并行性限制在最低限度,使大多数程序员可以自由地实现线性,顺序代码。

至于C ++,我发现这种完全的理念是将一个字符串,一个线程和一台咖啡机无差别地包装在同一句法上,这是一个灾难性的设计选择。

C ++允许你从任何东西中创建一个多处理器同步对象,就像你要分配一个纯粹的字符串一样,这类似于在同一个展示柜中的喷枪旁边展示一支突击步枪。

毫无疑问,很多人都是通过出售突击步枪和喷枪的想法来谋生,毕竟,并没有那么不同。但他们仍然是。

答案 1 :(得分:1)

需要考虑两件事:

  1. 使用C ++ 11 atomic时,只有一个操作是原子的。但通常当你想使用互斥锁来保护更大的代码区域时。

  2. 如果将std :: atomic用于编译器无法在机器代码中转换为原子操作的类型,则编译器必须为该操作插入互斥锁。

  3. 总的来说,您可能希望坚持使用互斥锁,并且只对性能关键部分使用无锁代码,或者如果您要实现自己的结构以用于同步。

答案 2 :(得分:0)

你错过了什么。虽然无锁数据结构确实使用了您提到的原语,但只是调用它们的存在不会为您提供无锁队列。

答案 3 :(得分:0)

由于没有C ++,无锁代码并不简单,操作系统通常在C / Assembly中为内存排序和防护提供类似的东西。

C ++提供更好的&更容易使用的界面(当然更标准化,所以你可以在多个操作系统,多个机器结构使用相同的界面),但如果你只针对一个特定的类型,用C ++编程无锁代码不比没有C ++简单操作系统/机器结构。