标签: stdatomic

检查前提条件是否存在原子增量,即原子值小于指定值?

在新标准 C++ 原子递增操作中,在递增值之前检查先决条件是否表明原子值小于指定值?

我可以比下面的代码更容易、更快吗?

int atomic_inc(std::atomic_int& val, int less_than) {
 int new_val;
 int old_val = val.load();
 do
 {
   if (old_val > less_than) return old_val;
   new_val = old_val + 1;
 } while (!val.compare_exchange_weak(old_val, new_val));

 return new_val;
}
Run Code Online (Sandbox Code Playgroud)

如果有人不知道compare_exchange_weak是如何工作的:compare_exchange_weak读取val,与old_val进行比较,如果不相等则将val保存到old_val。如果相等则将new_val保存到val。

c++ atomic atomic-swap c++11 stdatomic

7
推荐指数
1
解决办法
3698
查看次数

c ++ 11 std :: atomic_flag,我正确使用它吗?

我有一个简单的布尔值,我需要以线程安全的方式进行测试和设置.如果一个线程已经在工作,我希望第二个线程退出.如果我理解std::atomic_flag正确,这应该工作正常.但是,我不自信我理解std::atomic_flag正确:)我似乎无法在网上找到很多简单的例子,除了这个螺旋锁示例:

// myclass.cpp
#using <atomic>

namespace  // anonymous namespace
{
    std::atomic_flag _my_flag = ATOMIC_FLAG_INIT;
}  // ns

myclass::do_something()
{
    if ( !::_my_flag.test_and_set() ) )
    {
        // do my stuff here; handle errors and clear flag when done
        try
        {
            // do my stuff here
        }
        catch ( ... )
        {
            // handle exception
        }

        ::_my_flag.clear();  // clear my flag, we're done doing stuff
    }
    // else, we're already doing something in another thread, let's exit
} …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading c++11 stdatomic

7
推荐指数
1
解决办法
6663
查看次数

错误C2280:尝试引用已删除的函数(atomic <int>)

我有一个类型class A的成员变量._atomicVarstd::atomic<int>

#include <atomic>

class A
{
public:
    A();
    ~A();

private:
    std::atomic<int> _atomicVar;
};
Run Code Online (Sandbox Code Playgroud)

如果我构建项目,我会收到以下错误:

error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)' : attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

我主要是一名C#开发人员,所以我还不知道C++的每一个细节.我不知道我在哪里使用复制文件atomic<int>.
我也尝试初始化_atomicVar:

std::atomic<int> _atomicVar { 0 };
Run Code Online (Sandbox Code Playgroud)

......但那没用.
我希望_atomicVar(没有显式初始化)将使用默认值初始化int.
你能告诉我为什么会出现这个错误吗?

c++ c++11 stdatomic

7
推荐指数
1
解决办法
1万
查看次数

C中的原子递减和测试

我正在C中实现一个需要使用多个线程的引用计数系统.因此,我需要一种方法来减少整数引用计数,并测试一次原子操作结果是否为零.我可以使用C11 stdatomic.h,但似乎没有减量和测试操作.

这是最好的(即最便携的)方式吗?我可以使用这些stdatomic.h功能来实现吗?


这是引用计数(伪代码)的核心:

retain(object) {
    ++object.ref_count;  // pretty easy to make this atomic
} 

release(object) {
    if (--object.ref_count == 0)  // need this to be atomic also
        free(object)
}
Run Code Online (Sandbox Code Playgroud)

c atomic c11 stdatomic

7
推荐指数
1
解决办法
1019
查看次数

重新排序C ++中的原子操作

假设我有2个线程:

int value = 0;
std::atomic<bool> ready = false;

thread 1:
value = 1
ready = true;

thread 2:
while (!ready);
std::cout << value;
Run Code Online (Sandbox Code Playgroud)

这个程序能输出0吗?

我读到了有关C ++内存模型的信息-具体来说,是顺序一致性,我认为这是默认设置,但并不是特别清楚。是仅要求编译器相对于彼此以正确的顺序放置原子操作,还是相对于所有其他操作以正确的顺序放置原子操作?

c++ multithreading memory-model stdatomic

7
推荐指数
1
解决办法
818
查看次数

std::atomic_flag 不提供加载或存储操作有什么缺点吗?(自旋锁示例)

将 astd::atomic_flag与 an std::atomic_bool(又名std::atomic<bool>)进行比较,在我看来, astd::atomic_flag只是具有更简单的界面。它仅提供测试+设置和清除标志,同时std::atomic_bool还为多个运算符提供重载。

我的一个问题是关于术语的:“加载或存储操作”是什么意思?这是否意味着不能任意读取和修改 astd::atomic_flag的值?

此外,我想知道,将 astd::atomic_bool用于自旋锁时会更快吗?在我看来,std::atomic_flag在自旋锁期间总是必须读取和写入:

while (my_atomic_flag.test_and_set()); // spin-lock
Run Code Online (Sandbox Code Playgroud)

而 anstd::atomic_bool只需执行读取操作(假设原子 bool 是无锁实现的):

while (my_atomic_bool); // spin-lock
Run Code Online (Sandbox Code Playgroud)

严格来说,a 是否std::atomic_flag比 a 更有效率std::atomic_bool,或者反过来也可能吗?自旋锁应该使用什么?

c++ atomic c++11 stdatomic

7
推荐指数
1
解决办法
2072
查看次数

为什么GCC原子内建函数需要附加的“通用”版本?

根据https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html,存在:

type __atomic_load_n (type *ptr, int memorder)
Run Code Online (Sandbox Code Playgroud)

和(“通用”):

void __atomic_load (type *ptr, type *ret, int memorder)
Run Code Online (Sandbox Code Playgroud)

然后

void __atomic_store_n (type *ptr, type val, int memorder)
Run Code Online (Sandbox Code Playgroud)

和(“通用”)

void __atomic_store (type *ptr, type *val, int memorder)
Run Code Online (Sandbox Code Playgroud)

等等

后一个版本有什么通用性(前一个版本不通用),为什么需要它们?

c gcc intrinsics stdatomic

7
推荐指数
1
解决办法
53
查看次数

std::atomic 中的任何内容都是免等待的?

如果T是 C++ 基本类型,并且如果std::atomic<T>::is_lock_free()返回true,那么是否有任何东西std::atomic<T>是无等待的(不仅仅是无锁的)?像, load, store, fetch_add, fetch_sub, compare_exchange_weak, 和compare_exchange_strong

您是否还可以根据 C++ 标准中指定的内容以及 Clang 和/或 GCC(您选择的版本)中实现的内容进行回答。

我最喜欢的无锁和无等待定义来自C++ Concurrency in Action(免费提供)。如果满足下面的第一个条件,则算法是无锁的,如果满足以下两个条件,则是无等待的:

  1. 如果访问数据结构的线程之一在其操作中途被调度程序挂起,则其他线程必须仍然能够完成其操作而无需等待挂起的线程。
  2. 无论其他线程的行为如何,访问数据结构的每个线程都可以在有限步数内完成其操作。

c++ lock-free language-lawyer stdatomic wait-free

7
推荐指数
1
解决办法
658
查看次数

切换atomic_bool的有效方法

如果我有atomic_bool flag;,我如何编写 C 代码来切换它,使其原子、可移植且高效?关于“高效”,我希望它能够在 x86_64 上组装到lock xorb $1, flag(%rip). “显而易见”的东西flag = !flag;已经被淘汰了,因为它实际上不是原子的。我的下一个猜测是flag ^= true;,它在 GCC 上组装成一团糟:

        movzbl  flag(%rip), %eax
0:
        movb    %al, -1(%rsp)
        xorl    $1, %eax
        movl    %eax, %edx
        movzbl  -1(%rsp), %eax
        lock cmpxchgb   %dl, flag(%rip)
        jne     0b
Run Code Online (Sandbox Code Playgroud)

Clang 上的混乱:

        movb    flag(%rip), %al
0:
        andb    $1, %al
        movl    %eax, %ecx
        xorb    $1, %cl
        lock            cmpxchgb        %cl, flag(%rip)
        jne     0b
Run Code Online (Sandbox Code Playgroud)

然后我尝试通过这样做来指定较弱的内存顺序atomic_fetch_xor_explicit(&flag, true, memory_order_acq_rel);。这实现了我在 Clang 上想要的功能,但是 GCC 现在完全无法使用error: operand type '_Atomic …

c x86 atomic compiler-optimization stdatomic

7
推荐指数
1
解决办法
610
查看次数

在 futex 系统调用中使用 std::atomic

在 C++20 中,我们能够在原子变量上休眠,等待它们的值改变。我们通过使用std::atomic::wait方法来做到这一点。

不幸的是,虽然wait已经标准化,wait_forwait_until不是。这意味着我们不能在超时的原子变量上睡觉。

无论如何,使用 Windows上的WaitOnAddress和Linux 上的futex系统调用在幕后实现原子变量睡眠。

解决上述问题(无法在具有超时的原子变量上休眠),我可以在 Windows 上将内存地址传递std::atomic给 toWaitOnAddress并且它将(有点)在没有 UB 的情况下工作,因为该函数void*作为参数获取,并且强制转换std::atomic<type>为有效void*

在 Linux 上,不清楚是否可以std::atomicfutex. futex得到无论是uint32_t*int32_t*(取决于你读这手册),铸造std::atomic<u/int>u/int*为UB。另一方面,手册说

uaddr 参数指向 futex 字。 在所有平台上,futex 都是四字节整数,必须在四字节边界上对齐。在 futex_op 参数中指定要对 futex 执行的操作;val 是一个值,其含义和目的取决于 futex_op。

提示alignas(4) std::atomic<int>应该有效,只要类型具有 4 个字节的大小和 4 的对齐方式,它是哪种整数类型并不重要。

此外,我已经看到很多地方实现了这种结合原子和 futexes 的技巧,包括boostTBB

那么以非 …

c++ linux futex stdatomic c++20

7
推荐指数
1
解决办法
230
查看次数