问题标签 [stdatomic]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
741 浏览

multithreading - 在另一个线程中读取变量

我正在使用 linux,我有两个在另一个线程中读/写的变量。偶尔(100 毫秒)ThreadB 会读取变量的状态并执行一些操作。它基本上是一个while(1){ dosomething(); usleep(); }. 我担心变量会被缓存并且永远不会更新。

确保优化后循环正常工作的最佳方法是什么?我在想volatile应该做这项工作,但我听说它有时不起作用。两个循环都不经常运行(10ms+)。访问它们的最简单直接的方法是什么?我正在使用 C++11

我有点不确定如何使用std::atomic<int>. 我可以像普通的 int 变量一样使用它,它会按预期工作吗?

0 投票
3 回答
5236 浏览

c++ - 用于无锁单链表的原子 shared_ptr

我想知道是否可以为任何“常见”架构(如 x64 或 ARMv7 / ARMv8)创建无锁、线程安全的共享指针。

在cppcon2014 上关于无锁编程的演讲中,Herb Sutter 展示了无锁单链表的(部分)实现。该实现看起来很简单,但它依赖于shared_ptr标准库中尚不存在的原子实现或使用专用std::atomic...函数。这一点尤其重要,因为单个 push/pop 调用可能会调用多个原子加载/存储和compare_exchange操作。

我看到的问题(我认为谈话中的一些问题朝着相同的方向发展)是,要使这成为一个实际的无锁数据结构,这些原子操作本身必须是无锁的。我不知道无std::atomic...锁函数​​的任何标准库实现 - 至少通过简短的 google / SO 搜索 - 我也没有找到关于如何为std::atomic<std::shared_ptr>.

现在在我浪费时间之前,我想问一下:

  • 你知道,如果有可能写一个无锁的原子共享指针吗?
  • 是否已经存在我忽略的任何实现,并且 - 理想情况下 - 甚至与您对 a 的期望兼容std::atomic<std::shared_ptr>?对于提到的队列,它特别需要CAS- 操作。
  • 如果没有办法在当前架构上实现这一点,那么与受锁保护的“普通”链表相比,您是否看到 Herb 的实现有任何其他好处?

作为参考,这里是 Herb Sutter 的代码(可能包含我的拼写错误):

请注意,在此实现中, a 的单个实例shared_ptr可以由多个不同的线程访问/修改。它可以被读取/复制、重置甚至删除(作为节点的一部分)。所以这不是关于多个不同shared_ptr的对象(管理同一个对象)是否可以在没有竞争条件的情况下被多个线程使用——这对于当前的实现已经是正确的并且是标准所要求的——而是关于对单个指针的并发访问例如,对于标准共享指针来说,它不会比对原始指针的相同操作更具线程安全性。


解释我的动机:
这主要是一个学术问题。我无意在生产代码中实现我自己的无锁列表,但我觉得这个话题很有趣,乍一看,Herb 的介绍似乎是一个很好的介绍。然而,在思考这个问题和@sehe 对我的回答的评论时,我想起了这个演讲,又看了一遍,意识到如果原始操作需要锁,那么将 Herb 的实现称为无锁并没有多大意义(他们目前所做的)。所以我想知道,这是否只是当前实现的限制还是设计中的根本缺陷。

0 投票
0 回答
129 浏览

c++ - 这是对“memory_order_relaxed”的正确使用吗?

我开始(谨慎地)使用 C++11 中引入的原子原语。一个非常简单的用例是在存储我的应用程序运行时配置的std::atomic<integral>全局settings类中使用。

这个类有一堆静态方法来访问在程序启动时初始化的全局变量。以前对这些全局变量的访问受以下保护mutex

有了std::atomic,我现在有:

现在,我在这里阅读有关原子操作的内存顺序规范:http: //en.cppreference.com/w/cpp/atomic/memory_order

对于这个非常微不足道的用例场景,我可以将load()调用修改为:

请注意,这里唯一的要求是检查和/或更改全局设置的操作必须是原子的。这些操作不是任何无锁算法的一部分,它们不需要用任何东西排序(至少目前是这样)。

从我所做的一些研究来看,似乎共识是避免放松操作,除非一个人是专家(显然我不是:),所以我想知道通过应用这个改变我会陷入哪个陷阱(如果有的话)。

0 投票
0 回答
404 浏览

visual-c++ - SRWLock 与 std::atomic_flag 的性能

我有一个场景,SRWLock 与条件变量结合使用,std::atomic_flag 都可以满足我的需求。如果性能受到关注,是否有任何理由更喜欢其中一个?我有两个线程在共享资源上读取和写入数据,所以我目前使用 SRWLock 获取排他锁。

0 投票
2 回答
2536 浏览

c++ - memory_order_consume 和 memory_order_acquire 之间的区别

我有一个关于GCC-Wiki 文章的问题。在标题“总体摘要”下,给出了以下代码示例:

线程 1:

线程 2:

据说,如果所有 store 都是release并且所有 load 都是acquire,那么线程 2 中的 assert 不会失败。这对我来说很清楚(因为线程 1 中对 x 的存储与线程 2 中来自 x 的负载同步)。

但现在到了我不明白的部分。也有人说,如果所有 store 都是release并且所有 load 都是consume,结果是一样的。y 的负载是否有可能在 x 的负载之前被提升(因为这些变量之间没有依赖关系)?这意味着线程 2 中的断言实际上可能会失败。

0 投票
0 回答
89 浏览

c++ - 标准::原子不支持?

我正在尝试std::atomic<>struct sigactionin一起使用,std::vector但我的测试用例在 Clang 和 GCC 中都因链接器错误而失败。这是为什么?我支持所有类型,即使是非基本类型。

请参阅http://coliru.stacked-crooked.com/a/df4cfcbe48ecc992。结果是

0 投票
1 回答
261 浏览

c++ - atomic int 集合的线程安全

我有以下类包装了一个原子整数向量(std::vector< std::atomic_int >

向量在对象构造时的大小是正确的,并且不会改变大小。有用于获取、设置原子整数的常用访问器和修改器,但没有警卫/互斥锁。

我想怀疑这可能不是线程安全的(它目前在单线程模型中运行没有问题),但会欣赏任何观点。我想我主要关心的是无人看守的集合的线程安全,而不是它的元素。

0 投票
1 回答
404 浏览

c++11 - 测量原子增量与常规整数增量相比有多慢

最近的一次讨论让我想知道原子增量与常规整数增量相比有多昂贵。

我写了一些代码来尝试对此进行基准测试:

我遇到的麻烦是该程序在每次运行中都会产生截然不同的结果:

这使我相信基准测试代码本身可能存在错误。我错过了一些错误吗?我使用 std::chrono 进行基准测试不正确吗?还是由于操作系统中与原子操作有关的信号处理的开销而产生的时间差?

我可能做错了什么?

试验台:

编辑:使用 -O3 优化编译后更新了测试运行输出。

编辑:在运行测试以增加迭代次数并添加循环总和以防止按照 Adam 建议的循环增量进行优化后,我得到了更收敛的结果:

0 投票
2 回答
552 浏览

c++ - 可以在 C++ 内存模型中合并原子负载吗?

考虑下面的 C++ 11 片段。对于 GCC 和 clang,这编译为两个(顺序一致的)foo 负载。(编者注:编译器不优化原子,有关更多详细信息,请参阅此 Q&A,特别是http://wg21.link/n4455标准讨论这可能产生的问题,标准没有为程序员提供解决工具。这种语言-lawyer Q&A 是关于当前标准的,而不是编译器所做的。)

C++ 内存模型是否允许编译器将这两个加载合并为一个加载并为 x 和 y 使用相同的值?

(编者注:这是标准组正在研究的内容: http ://wg21.link/n4455和http://wg21.link/p0062。目前纸上的标准允许不受欢迎的行为。)


我认为它无法合并这些负载,因为这意味着轮询原子不再起作用,但我在内存模型文档中找不到相关部分。

0 投票
3 回答
2123 浏览

c++ - 在地图中就地构造一个不可移动的对象

我正在尝试在包含原子的地图中构造一个对象,因此它既不能复制也不能移动 AFAICT。

我对 C++参考的阅读是 mapemplace应该能够做到这一点。但是由于已删除或不存在构造函数,以下代码无法编译。使用make_pair没有帮助。

这是可能的,如果没有,为什么不呢?

编辑:编译器是 gcc 4.8.1,在 Linux 上