标签: atomic

std::atomic<bool> 执行保证?

我知道 std::atomic 应该具有明确定义的行为,但我找不到这个问题的易于理解的在线答案:Do std::atomic.load() 和 .store() 有执行保证吗?

如果两个线程尝试对同一个 std::atomic 对象进行并发写入或读取,是否保证写入和读取都被执行?换句话说,写入或读取任务是否有可能根本无法完成?其中之一或两者会被阻止吗?或者它们保证是连续的?我不是这里询问操作顺序。我只是简单地询问手术是否会在未来某个未指定的时间进行。

c++ multithreading atomic stdatomic

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

C++ 在不同进程之间共享atomic_int64_t?

我正在使用 C++ 多处理,使用共享内存将数据从一个传递到另一个。我将一个数组放入共享内存中。进程A将数据复制到数组中,进程B将使用数组中的数据。然而,进程B需要知道数组中有多少项。

目前我正在使用管道/消息队列将数组大小从A传递到B。但我想我可能会在共享内存中放置一个原子变量(如atomic_uint64_t),在进程A中修改它并在进程B中加载它。但是我有以下问题。

  1. C++中的原子变量在进程之间仍然是原子的吗?我知道原子是通过锁定缓存行来实现的,其他线程或进程都不能修改原子变量。所以我认为答案是肯定的。
  2. 我究竟应该如何在之间共享原子变量?谁能举个例子吗?

c++ atomic multiprocessing

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

带有原子等待的 C++20 互斥锁

从 C++20 std::atomics 开始,有等待和通知操作。使用 is_always_lock_free 我们可以确保实现是无锁的。使用这些积木构建无锁互斥锁并不那么困难。在简单的情况下,锁定将是比较交换操作,或者如果互斥体被锁定则等待。这里最大的问题是这是否值得。如果我可以创建这样的实现,那么 STL 版本很可能会更好、更快。然而,我仍然记得当我在 2016 年看到 QMutex 如何优于 std::mutex QMutex 与 std::mutex时,我是多么惊讶。那么您认为我应该尝试这样的实现还是 std::mutex 的当前实现已经足够成熟,可以进行远远超出这些技巧的优化?

更新 我的措辞不是最好的,我的意思是实现可以在快乐的路径上无锁(从未锁定状态锁定)。当然,如果我们需要等待获取锁,我们应该被阻塞并重新调度。在大多数平台上,atomic::wait 很可能不是通过简单的自旋锁实现的(现在让我们忽略极端情况),所以基本上它实现了 mutex::lock 所做的相同的事情。所以基本上,如果我实现这样一个类,它将执行与 std::mutex 完全相同的操作(同样在大多数流行平台上)。这意味着 STL 可以在支持这些技巧的平台上的互斥实现中使用相同的技巧。就像这个 spinlock,但我会使用原子等待而不是旋转。我应该相信我的 STL 实现是他们这样做的吗?

c++ mutex atomic stdatomic c++20

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

Java 8 实现比较和交换(不是比较和设置!)

在java 17中,AtomicReferencecompareAndExchange类似于 的方法compareAndSet,但它不返回布尔值,而是返回原子操作之前的值。我需要它来实现自定义并发结构。

由于项目的限制,我只能使用 Java 8 功能。一些挖掘揭示了VarHandle其中有compareAndExchange。但是,VarHandle需要 Java 9。

因此,看来我必须compareAndExchange亲自实施了。但如何利用现有方法高效地做到这一点呢?(那么compareAndExchangeWeak版本呢?)

(顺便说一句,我不能依赖任何第三方库)

java atomic atomicreference compare-and-swap java-8

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

C++ 顺序一致性并且发生在关系之前

    #include <atomic>
    #include <thread>
    #include <assert.h>
    std::atomic<bool> x,y;
    std::atomic<int> z;
    void write_x()
    {
        x.store(true,std::memory_order_seq_cst); // 1
    }
    void write_y()
    {
        y.store(true,std::memory_order_seq_cst); // 2
    }
    void read_x_then_y()
    {
        while(!x.load(std::memory_order_seq_cst)); // 3
        if(y.load(std::memory_order_seq_cst)) // 4
            ++z;
    }
    void read_y_then_x()
    {
        while(!y.load(std::memory_order_seq_cst)); // 5
        if(x.load(std::memory_order_seq_cst)) // 6
            ++z;
    }
    int main() {
        x=false;
        y=false;
        z=0;
        std::thread a(write_x);
        std::thread b(write_y);
        std::thread c(read_x_then_y);
        std::thread d(read_y_then_x);
        a.join();
        b.join();
        c.join();
        d.join();
        assert(z.load()!=0); 
    }
Run Code Online (Sandbox Code Playgroud)

在《C++ Concurrency in Action》一书中,作者在谈论顺序一致性时给出了这个例子,并说assert永远不能触发,因为

[1] 或 [2] 必须首先发生...并且如果一个线程看到 x==true 然后随后看到 y==false,这意味着按照总顺序,对 …

c++ multithreading atomic memory-model stdatomic

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

`int` 是原子类型吗?

引用gnu

实际上,您可以假设 int 是原子的。您还可以假设指针类型是原子的;非常方便。这两个假设在 GNU C 库支持的所有机器上以及我们所知的所有 POSIX 系统上都是成立的。

这怎么可能?我见过的与锁相关的所有示例都是用int计数器制作的,例如https://www.delftstack.com/howto/c/mutex-in-c/

c concurrency gcc gnu atomic

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

为什么Go中支持atomic.Load和atomic.Store?

我认为atomic.Load(addr)应该等于*addr并且atomic.Store(addr, newval)应该等于*addr = newval。那么为什么这样做(使用*addror *addr = newval)不是原子操作呢?我的意思是它们最终会被解释为只是一条 cpu 指令(这是原子的)?

atomic go

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

C++11 中的原子是否缓存寄存器中的可重复读取,或者它们只是原子的?

原子是否将可重复读取缓存在寄存器中?或者它们只是原子的,即读取可能不会分成多个部分?

MSVC++、clang++ / clang-cl 和 g++ 不会在没有内存排序的情况下缓存原子读取:

#include <atomic>

using namespace std;

int x( atomic_int const &ai )
{
    int
        a = ai.load( memory_order_relaxed ),
        b = ai.load( memory_order_relaxed );
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

克++:

movl    (%rdi), %edx
movl    (%rdi), %eax
addl    %edx, %eax
ret
Run Code Online (Sandbox Code Playgroud)

铿锵-cl:

mov eax, dword ptr [rcx]
add eax, dword ptr [rcx]
ret
Run Code Online (Sandbox Code Playgroud)

CL:

mov edx, DWORD PTR [rcx]
mov eax, DWORD PTR [rcx]
add eax, edx
ret 0`
Run Code Online (Sandbox Code Playgroud)

c++ atomic c++11 stdatomic

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

在 C/C++ 中原子按位与字节的最佳方法?

目前正在使用 GCC 查看 C/C++ 中的原子操作,发现内存中自然对齐的全局变量具有原子读取和写入。

然而,我试图按位与一个全局变量,并注意到它归结为一个读取-修改-写入序列,如果有多个线程对该字节值进行操作,那么这会很麻烦。

经过一番研究,我选择了这两个例子:

C 示例- GCC 扩展__sync_fetch_and_and

#include <stdio.h>
#include <stdint.h>

uint8_t byteC = 0xFF;

int main() {
    __sync_fetch_and_and(&byteC, 0xF0);
    printf("Value of byteC: 0x%X\n", byteC);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++ 示例- 使用原子的 C++11fetch_and

#include <iostream>
#include <atomic>

std::atomic<uint8_t> byteCpp(0xFF);

int main() {
    byteCpp.fetch_and(0xF0);
    std::cout << "Value of byteCpp: 0x" << std::hex << static_cast<int>(byteCpp.load()) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

其他示例如下,但它们似乎不太直观且计算成本更高。

用一个pthread_mutex_lock

uint8_t byte = 0xFF;
pthread_mutex_t byte_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&byte_mutex);
byte …
Run Code Online (Sandbox Code Playgroud)

c c++ atomic stdatomic

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

是否有一个平台没有本机指针大小的原子,但具有其他大小的原子?

我正在对广泛使用的开源库进行重构,并希望使其尽可能强大。

目前,如果支持的话,它会使用原子size_t变量,但我想知道它是否会错过一些不起眼的平台,例如,32 位原子同时具有 64 位指针。

c++ multithreading atomic cpu-architecture rust

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