这是`std::atomic<T*>`的有效用法吗

问题描述 投票:0回答:1
#include <iostream>
#include <atomic>
#include <thread>
#include <cassert>

struct Node{
    int value;
    std::atomic<Node*> next;
};
int main(){
    std::atomic<Node*> ptr = (Node*)0;
    auto t1 = std::thread([&ptr](){
        auto r = new Node{1,std::atomic<Node*>{(Node*)nullptr}};  // #1
        ptr.store(r,std::memory_order::relaxed);
    });
    auto t2 = std::thread([&ptr](){
        Node* r = nullptr;
        while(r==nullptr){
            r = ptr.load(std::memory_order::relaxed);
        }
        assert(r->value == 1); // #2
        assert(r->next.load(std::memory_order::relaxed) == nullptr); // #3
    });
    t1.join();
    t2.join();
}

#2
#3
是否能保证读取
#1
中写入的值?如果不是,请问原因是什么?

c++ atomic
1个回答
-1
投票

应该没问题,因为

ptr
只被分配一次,所以
r
在循环之后将始终具有
ptr
的非空值。像你一样读取 ptr->value 也很好。缺少一件事。
delete ptr;
退出前
main()

由于您使用的是

std::atomic<>
并且仅轻松加载/存储,因此您应该避免如此冗长,这将使您的代码更具可读性。考虑一下:

int main() {
    std::atomic<Node*> ptr = nullptr;
    auto t1 = std::thread([&ptr]() {
        ptr = new Node{1, nullptr};  // #1
    });
    auto t2 = std::thread([&ptr]() {
        Node* r = nullptr;
        while ((r = ptr) == nullptr) {
        }

        assert(r->value == 1);       // #2
        assert(r->next == nullptr);  // #3
    });
    t1.join();
    t2.join();

    delete ptr;
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.