标签: stdatomic

c++11:如何在compare_exchange_weak上产生“虚假失败”?

有没有一种方法可以让我们编写一些代码来为compare_exchange的“弱”版本产生“虚假失败”?虽然相同的代码应该可以很好地用于compare_exchange_strong?

我希望了解 2 个 api 的“弱”版本和“强”版本之间的真正区别,有任何示例吗?

多谢!

c++ cpu-architecture stdatomic

5
推荐指数
1
解决办法
314
查看次数

C++ Concurrency in Action 中危险指针的实现是否存在缺陷?

我正在阅读《C++ Concurrency in Action》第二版。下面的代码来自清单 7.6。它pop()使用危险指针来实现堆栈。

std::shared_ptr<T> pop() {
  std::atomic<void*>& hp = get_hazard_pointer_for_current_thread();
  node* old_head = head.load();  // #1
  do {
    node* temp;
    do {
      temp = old_head;
      hp.store(old_head);        // #2
      old_head = head.load();    // #3
    } while (old_head != temp);  // #4
  } while (old_head &&
           !head.compare_exchange_strong(old_head, old_head->next));
  hp.store(nullptr);
  // ...
}
Run Code Online (Sandbox Code Playgroud)

书中解释了内循环的作用:

您必须在while循环中执行此操作,以确保node在读取旧head指针#1和设置危险指针#2之间没有删除。在此窗口期间,没有其他线程知道您正在访问该特定节点。幸运的是,如果旧head节点要被删除,head那么它本身一定已经发生了变化,因此您可以检查这一点并继续循环,直到您知道该head指针仍然具有与您设置危险指针相同的值#4

根据 的实现,如果另一个线程在和之间pop删除了头节点,则将被修改为新节点。pop …

c++ concurrency multithreading atomic stdatomic

5
推荐指数
1
解决办法
434
查看次数

std::atomic&lt;&gt; 用于 avr-gcc

我想知道是否可以编写std::atomic<>供 AVR \xc2\xb5C 使用的内容。__atomic_xxx()不幸的是,avr-gcc 中没有实现内置函数。

\n

据我了解,uint8_tAVR 上的基本加载/存储是原子的,但例如operator++()不是因为它意味着 rmw 循环。因此,对于这些操作,必须禁用中断,因为这是该硬件上唯一的并发形式。对于更大的类型,uint8_t甚至operator=(T)需要防止中断。

\n

另一方面,必须对模板的数据成员应用内存屏障:例如,该数据成员具有必须使用的std::atomic<>名称来完成机器上的实际加载/存储。valueasm volatile("" : "+m" (value));

\n

这足以实施吗std::atomic<>

\n

由于此实现是无锁的,因此它应该可用于该硬件上的 ISR。

\n

如果要实现这一点,std::atomic<>这将导致ISR内的机器代码效率低下,因为不必要的中断禁用和/或内存屏障会阻止优化。

\n

std::atomic<>好吧,这可以通过扩展不安全操作的接口来规避

\n

另一方面:std::atomic_ref<>在 ISR 之外实施和使用它是否更可行?

\n

c++ avr interrupt avr-gcc stdatomic

5
推荐指数
0
解决办法
170
查看次数

为什么释放序列只能包含读-修改-写而不能包含纯写

对原子对象M执行释放操作A后,M的修改顺序的最长连续子序列包括:

  1. 由执行 A 的同一线程执行写入。(C++20 之前)
  2. 任何线程对 M 进行原子读-修改-写操作。被称为以 A 为首的释放序列。
  • Q1:为什么需要释放顺序的概念?

    A1:参见“释放顺序”是什么意思?

  • Q2:C++20中第一项被删除了吗?

  • 问题 3:为什么读-修改-写操作符合发布顺序,而纯写操作则不然?

    宽松的 RMW 有什么特别之处,可以让它们形成一个链,而不需要成为获取加载和释放存储?是用计算机体系结构术语,还是用 C++ 语言形式主义?或者换句话说,硬件如何支持原子 RMW 的释放序列语义,但具有中断连接的纯存储?

c++ atomic cpu-architecture memory-model stdatomic

5
推荐指数
0
解决办法
86
查看次数

是否会在其他线程中始终以相同顺序看到对不同线程中不同位置的两次原子写操作?

与我之前的问题类似,请考虑以下代码

-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};

-- Thread 1 --
x.store(1, std::memory_order_release);

-- Thread 2 --
y.store(2, std::memory_order_release);

-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);   // x first
int r2 = y.load(std::memory_order_acquire);

-- Thread 4 --
int r3 = y.load(std::memory_order_acquire);   // y first
int r4 = x.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)

怪异的结果 r1==1, r2==0,并r3==2, r4==0有可能在C ++ 11内存模型下,这种情况下?如果我要全部替换std::memory_order_acq_rel成该std::memory_order_relaxed怎么办?

在x86上,这样的结果似乎是被禁止的,请参见此SO问题,但我一般是在询问C ++ 11内存模型。

奖励问题:

我们都同意,与std::memory_order_seq_cst怪异的结果不会在C ++ 11被允许。现在,赫伯·萨特(Herb Sutter)在他著名的- …

c++ concurrency memory-model c++11 stdatomic

4
推荐指数
3
解决办法
540
查看次数

为什么只保证std :: atomic_flag无锁?

来自C++ Concurrency in Action:

std :: atomic和std :: atomic_flag之间的区别是std :: atomic可能不是无锁的; 实现可能必须在内部获取互斥锁,以确保操作的原子性

我想知道为什么.如果保证atomic_flag是无锁的,为什么它也不能保证atomic<bool>?这是因为会员功能compare_exchange_weak吗?我知道有些机器缺少单一的比较和交换指令,原因是什么?

multithreading atomic c++11 stdatomic

4
推荐指数
1
解决办法
802
查看次数

std :: atomic和std :: mutex之间的区别

如何使用std :: atomic <>

在上面的问题中,显然我们可以std::mutex用来保持线程安全.我想知道何时使用哪一个.

classs A
{
    std::atomic<int> x;

public:
    A()
    {
        x=0;
    }

    void Add()
    {
        x++;
    }

    void Sub()
    {
        x--;
    }     
};
Run Code Online (Sandbox Code Playgroud)

std::mutex mtx;
classs A
{
    int x;

public:
    A()
    {
        x=0;
    }

    void Add()
    {
        std::lock_guard<std::mutex> guard(mtx);
        x++;
    }

    void Sub()
    {
        std::lock_guard<std::mutex> guard(mtx);
        x--;
    }     
};
Run Code Online (Sandbox Code Playgroud)

multithreading mutex thread-safety c++11 stdatomic

4
推荐指数
1
解决办法
1089
查看次数

C++内存模型:seq_cst加载与seq_cst存储同步吗?

在C++内存模型中,所有顺序一致操作的所有加载和存储都有一个总顺序.我想知道这是如何与具有其他内存排序的操作交互,这些内存排序在顺序一致的加载之前/之后排序.

例如,考虑两个线程:

std::atomic<int> a(0);
std::atomic<int> b(0);
std::atomic<int> c(0);

//////////////
// Thread T1
//////////////

// Signal that we've started running.
a.store(1, std::memory_order_relaxed);

// If T2's store to b occurs before our load below in the total
// order on sequentially consistent operations, set flag c.
if (b.load(std::memory_order_seq_cst) == 1) {
  c.store(1, std::memory_order_relaxed)
}


//////////////
// Thread T2
//////////////

// Blindly write to b.
b.store(1, std::memory_order_seq_cst)

// Has T1 set c? If so, then we know our store to b occurred before …
Run Code Online (Sandbox Code Playgroud)

c++ atomic memory-model language-lawyer stdatomic

4
推荐指数
1
解决办法
186
查看次数

原子<T*>总是锁定自由吗?

在我的MAC OS上,atomic<T*>是免费的.

#include <iostream>
#include <atomic>

int main() {
    std::cout << std::atomic<void*>().is_lock_free() << std::endl;
    return 0;
}

output: 1
Run Code Online (Sandbox Code Playgroud)

我想知道是否atomic<T*>总是免费锁定?

有参考介绍吗?

c++ std c++11 stdatomic

4
推荐指数
1
解决办法
463
查看次数

为什么std :: atomic的默认构造函数不默认初始化底层存储值?

由于今天是美国的感恩节,所以我将被指定为土耳其来问这个问题:

Take something as innocuous as this. An atomic with a simple plain old data type such as an int:

atomic<int> x;
cout << x;
Run Code Online (Sandbox Code Playgroud)

The above will print out garbage (undefined) data. Which makes sense given what I read for the atomic constuctor:

(1) default constructor

Leaves the atomic object in an uninitialized state. An uninitialized atomic object may later be initialized by calling atomic_init.

Feels like an odd committee decision. But I'm sure they had their reasons. …

c++ initialization language-lawyer stdatomic

4
推荐指数
1
解决办法
99
查看次数