标签: stdatomic

我可以使用volatile sig_atomic_t来避免C++ 03中的互斥锁吗?

如果我在具有原子读取和递增/递减支持的硬件上,我是否可以使用volatile sig_atomic_tC++ 03来访问原子操作并避免使用完整的互斥锁,或者我必须等待C++ 11和std::atomic<int>

c++ mutex volatile stdatomic sig-atomic-t

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

用 32 位原子实现 64 位原子计数器

我想从原子 uint32s 拼凑一个 uint64 原子计数器。计数器有一个写入器和多个读取器。编写器是一个信号处理程序,所以它不能阻塞。

我的想法是使用低位的代数作为读锁。读取器重试,直到整个读取过程中生成计数稳定,并且低位未设置。

以下代码在内存排序的设计和使用中是否正确?有没有更好的办法?

using namespace std;
class counter {
    atomic<uint32_t> lo_{};
    atomic<uint32_t> hi_{};
    atomic<uint32_t> gen_{};

    uint64_t read() const {
        auto acquire = memory_order_acquire;
        uint32_t lo, hi, gen1, gen2;
        do {
            gen1 = gen_.load(acquire);
            lo = lo_.load(acquire);
            hi = hi_.load(acquire);
            gen2 = gen_.load(acquire);
        } while (gen1 != gen2 || (gen1 & 1));
        return (uint64_t(hi) << 32) | lo;
    }

    void increment() {
        auto release = memory_order_release;
        gen_.fetch_add(1, release);
        uint32_t newlo = 1 + lo_.fetch_add(1, release);
        if (newlo …
Run Code Online (Sandbox Code Playgroud)

c++ lockless c++11 stdatomic seqlock

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

为什么我的std :: atomic &lt;int&gt;变量不是线程安全的?

我不知道为什么我的代码不是线程安全的,因为它输出了一些不一致的结果。

value 48
value 49
value 50
value 54
value 51
value 52
value 53
Run Code Online (Sandbox Code Playgroud)

我对原子对象的理解是,它防止其中间状态暴露出来,因此当一个线程正在读取它而另一线程正在写入它时,它应该解决该问题。

我曾经认为我可以使用没有互斥量的std :: atomic来解决多线程计数器增量问题,但情况并非如此。

我可能误解了原子对象是什么,有人可以解释吗?

value 48
value 49
value 50
value 54
value 51
value 52
value 53
Run Code Online (Sandbox Code Playgroud)

c++ atomic thread-safety race-condition stdatomic

1
推荐指数
2
解决办法
117
查看次数

对于 CPU 无法原子操作的类型, std::atomic 有什么意义?

使用std::atomic而不是互斥锁的全部意义在于:

  1. 更高的多线程代码性能(阅读器之间没有争用);
  2. 发生严重争用时的性能变化较小(重试失败的 RMW 不如失去剩余时间片那么剧烈,因为持有互斥锁的线程已准备好运行但未运行);
  3. 与信号处理程序通信的能力。

当使用互斥表“模拟”操作的原子性时:

  1. 对于只需要一个修改操作的情况,性能充其量与用户互斥锁一样好;当多个操作顺序使用时,将需要进行多次加锁/解锁操作,从而降低代码效率。
  2. 性能将不会比使用显式用户互斥锁更可预测。
  3. 这种“模拟”原子性不能与阻塞其他代码(例如信号处理程序)的代码一起使用。

那么为什么对原子 CPU 操作的这种糟糕的模拟值得呢?中非无锁回退机制的用例是std::atomic什么?

c++ multithreading mutex lock-free stdatomic

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

以下代码是多线程增量计数器和打印的好解决方案吗?

请你给点意见好吗?你将做点什么不同的?我的意思是,你认为如果我用 std::task 或 std::mutex、std::condition_variable 等来做会更好吗?我用 2 个标志来控制线程是一种矫枉过正吗?

std::atomic<int> counter = { 0 };
std::atomic<bool> switchFlag = { false };
std::atomic<bool> finished = { false };
constexpr int MAX_NUM = 10;

void increment(){
    while (!finished.load()){
        if (!switchFlag.load()){
            std::cout << "incremented to =" << ++counter << '\n';
            switchFlag.store(true);
        }
    }
}

void print(){
    while (!finished.load()) {
        if (switchFlag.load()){
            std::cout << "counter=" << counter.load() << '\n';
            if (counter.load() >= MAX_NUM)
                finished.store(true);

            switchFlag.store(false);
        }
    }
}

int main() {
    auto t1 = std::thread(increment);
    auto …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading c++11 stdatomic

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

C++11:16 字节原子&lt;&gt; 变量是否在 16 字节边界上自动对齐,允许 CMPXCHG16B 指令?

16 字节atomic<>变量是否在 16 字节边界上自动对齐,从而允许编译器/运行时库有效地使用 x86CMPXCHG16B指令?或者我们应该根据风格总是手动指定alignas(16)所有这些变量?

c++ x86-64 memory-alignment compare-and-swap stdatomic

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

存储后的 std::atomic 地址

我似乎无法在商店之后获得原子对象的地址。

例如

std::atomic<int> i;
std::atomic<int>* p = &++i; // doesn't work
auto* p = &++i; // doesn't work
// below works:
++i;
auto* p = &i;
Run Code Online (Sandbox Code Playgroud)

这里发生了什么,为什么?

澄清一下:我知道它返回一个 r 值。为什么它不返回原始对象,this?这是一个有目的的设计选择还是一个疏忽?

更具体地说,这个要求的幕后发生了什么?

c++ operator-overloading language-lawyer stdatomic c++17

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

std::atomic&lt;T&gt;::operator= 如何为不可变类型实现?

我了解到线程之间通信的一种方法是共享一些原子数据结构。例如:

struct Point {
    int const x, y;
};

std::atomic<Point> some_point_in_shared_memory{Point{0, 0}};
Run Code Online (Sandbox Code Playgroud)

尽管Point::operator=(Point const &)被删除,但调用赋值运算符似乎没有问题std::atomic<Point>,如下所示:

some_point_in_shared_memory = Point{1, 2};
Run Code Online (Sandbox Code Playgroud)

如何实施此操作?

我可能会想到的一种解决方案是使用placement new在旧对象之上构造一个新对象,但显然它不是异常安全的。还是因为Point可以简单地复制而没关系?

c++ thread-safety exception-safety stdatomic

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

g++/gcc 是否支持 C++20 新的 atomic_flag 特性?

根据cppreference,c++20 具有丰富的(对我来说很有用)的atomic_flag操作支持。

但是,尚不清楚 gcc 是否还支持这些功能,在gnu 的功能摘要中找不到它们。我目前正在使用带有-c++=2aset 的版本 8 。

这段代码不能用 GCC8 编译:

#include <atomic>

int main() {
  std::atomic_flag myFlag = ATOMIC_FLAG_INIT;
  myFlag.test();
}
Run Code Online (Sandbox Code Playgroud)

error: ‘struct std::atomic_flag’ has no member named ‘test’

我不想通过安装较新版本的 g++ 来破坏我的构建环境,并且感谢任何可以报告atomic_flag版本 10 或更高版本支持的人。

c++ gcc g++ stdatomic

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

memory_order_relaxed 和可见性

考虑两个线程,T1 和 T2,它们分别存储和加载一个原子整数 a_i。让我们进一步假设,这家店在执行正在执行的负荷启动。以前,我的意思是绝对的时间意义。

T1                                    T2
// other_instructions here...         // ...
a_i.store(7, memory_order_relaxed)    // other instructions here
// other instructions here            // ...
                                      a_i.load(memory_order_relaxed)
                                      // other instructions here
Run Code Online (Sandbox Code Playgroud)

是否保证T2在加载后看到值7?

c++ atomic cpu-architecture stdatomic

1
推荐指数
2
解决办法
134
查看次数