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

C++ C+中的无锁数据结构+;=只是使用原子和内存排序?,c++,multithreading,c++11,concurrency,atomic,C++,Multithreading,C++11,Concurrency,Atomic,我曾经看到“无锁数据结构”这个术语,并认为“ooooo那一定很复杂”。然而,我一直在阅读“C++并发性在运行”,它似乎在编写一个无锁数据结构,您所做的只是停止使用互斥体/锁,并用原子代码替换它们(以及可能的内存排序障碍) 所以我的问题是——我是不是遗漏了什么?由于C++11,它真的那么简单吗?编写无锁数据结构只是用原子操作替换锁吗?您缺少了一些东西。虽然无锁数据结构确实使用您提到的原语,但简单地调用它们的存在并不能为您提供无锁队列。需要考虑两件事: 当使用C++11原子时,只有一个操作是原子的。

我曾经看到“无锁数据结构”这个术语,并认为“ooooo那一定很复杂”。然而,我一直在阅读“C++并发性在运行”,它似乎在编写一个无锁数据结构,您所做的只是停止使用互斥体/锁,并用原子代码替换它们(以及可能的内存排序障碍)


所以我的问题是——我是不是遗漏了什么?由于C++11,它真的那么简单吗?编写无锁数据结构只是用原子操作替换锁吗?

您缺少了一些东西。虽然无锁数据结构确实使用您提到的原语,但简单地调用它们的存在并不能为您提供无锁队列。

需要考虑两件事:

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

  • 如果将std::atomic与编译器无法在机器代码中转换为原子操作的类型一起使用,则编译器必须为该操作插入互斥体


  • 总体上,您可能希望坚持使用互斥体,只使用无锁代码来执行性能关键部分,或者如果您正在实现自己的结构以用于同步。C++/C++中,没有C++的无锁代码并不简单,操作系统通常为C/Assembly中的内存排序和隔离提供类似的功能

    C++提供了一个更好、更易于使用的接口(当然也更标准化,因此您可以在多个操作系统、多台机器结构中使用相同的接口),但是如果C++编程中只允许一种特定类型的OS/机器结构,那么C++编程的代码就不会比C++更简单。 如果您看不到互斥和原子访问之间的区别,那么您看待并行处理的方式就有问题,您编写的代码很快就会有问题

    最有可能的是,它的运行速度比同等的阻塞版本慢,如果你(或者更确切地说是你的同事)真的很不走运,它会偶尔抛出不一致的数据并随机崩溃

    更可能的是,它会将实时约束传播到应用程序的很大一部分,迫使您的同事浪费大量时间来处理他们和他们的软件本来可以很愉快地生活在没有的任意需求上,并诉诸各种迷信和良好做法,混淆他们的代码,使之屈服

    哦,好吧,只要模板的家伙和等待自由的家伙有他们的小乐趣


    并行处理,无论是阻塞处理还是假定的无等待处理,本质上都是资源消耗、复杂且实现成本高昂的。设计一个从非平凡的并行处理中获得真正优势的软件体系结构是专家们的工作

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

    对于C++,我发现在同一个语法错误中,一个字符串、一个线程和一个咖啡机的整体包装理念是一个灾难性的设计选择。p> C++允许你用任何东西创建一个多处理器同步对象,就像你只分配一个字符串一样,这类似于在同一个展示柜中把突击步枪放在水枪旁边


    毫无疑问,许多人靠推销突击步枪和水枪毕竟没什么不同的想法谋生。但是,他们仍然是。

    你能用一个例子来说明为什么不是这样吗?我之所以这样问,是因为《行动中的并发》(Concurrency in Action)一书第7章似乎暗示原子已经足够了。@meza原子已经足够了,如果你使用正确的算法并且非常小心(偶尔会在代码中查找非阻塞hashmap,Cliff Click for Java的hashmap是最有名的)。只是使算法比普通的阻塞版本复杂得多。我认为你可以将内存排序与原子相结合,产生互斥的等效效果,而不是“等效”。相似之处在于数据不会被覆盖,但互斥体仍然是阻塞同步对象,而原子只是防止处理器间读/写操作相互中断。任何工作的非阻塞数据结构都不会在任何地方“传播实时约束”——这意味着什么?见鬼,考虑到大多数代码都不会在RT操作系统上运行,那么一开始就有这样一个约束的想法是有缺陷的。在实践中,非阻塞是实现的一个有用属性,并封装在实际代码中(与阻塞版本相比,可能有一些限制-某些操作无法成为非阻塞)。因此,您的经验是在嵌入式领域使用一些古老、非常奇怪的框架(通常是软件工程的典范),但当大多数人谈论“无锁数据结构”时他们正在谈论数据结构,并且那些清楚地定义了实现与调用方分离的接口。仍然应该把实现留给专家,但是使用它们是不同的。@ Voo我的观点是正确的。C++ 11语法糖不仅提供了对数据结构的访问,而且还提供了对裸组件的访问。我认为OP的问题是这个问题的一个很好的例子。