http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange处 ,以下示例代码作为std::atomic_compare_exchange_weak使用示例std::atomic_compare_exchange_weak

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while(! std::atomic_compare_exchange_weak(s->head, head, n));
}

我的理解是,当我认为希望将s->headhead比较时,这具有将*(s->head)head比较的效果。 在此示例中, std::atomic_compare_exchange_weak的第一个参数应该为&(s->head) ,还是我缺少某些内容?

更新: std::atomic_compare_exchange_weak的规范说:

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;

效果 :以原子方式比较对象指向的内存的内容,以便与预期的对象相等。

我认为这是将*objectexpected相比较,但是进一步的研究表明,实际含义是*object*expected相比较(即,“处于expected ”的意思是“由expected指向”)。 这意味着我的原始问题的答案是“不,不需要在cppreference的示例代码中使用s->head的地址”。 但事实上, object必须指向一个std::atomic<T>和预期必须指向一个T使得我很难弄清楚如何在cppreference纠正代码,以便它可以编译。 我们想将列表的头部与列表的头部的副本进行比较,但是如果列表的头部的类型为std::atomic<T>* ,则如果列表的头部必须为T*类型打电话std::atomic_compare_exchange_weak是编译的,我无法找到一个方法来分配std::atomic<T>*T*没有reinterpret_cast 即使这样, std::atomic_compare_exchange_weak的第三个参数也必须是T类型,但是cppreference的示例显示第二个和第三个参数都属于同一类型。 这向我暗示了cppreference的示例已损坏。 我试图修复它,但是我不得不使用感觉不对的reinterpret_cast

有趣的是,在尝试找出这些东西时,我在msdn页面上签出了std::atomic_compare_exchange_weak ,但我很沮丧地看到该页面显示了std::atomic_compare_exchange_*strong*的原型!

有人可以张贴使用std::atomic_compare_exchange_weak合理代码在单链列表的前面插入节点吗? 无需担心ABA问题或做任何花哨的事情。 我只想看看可以编译的骨架代码。

===============>>#1 票数:2 已采纳

一个正确的例子是:

struct list {
    std::atomic<node*> head;
};

...

void append(list* s, node* n)
{
    node* head;
    do {
        head = s->head;
        n->next = head;
    } while (!std::atomic_compare_exchange_weak(&(s->head), &head, n));
    // or while (!s->head.compare_exchange_weak(head, n));
}

list::head必须是std::atomic对象,除非您想处理未定义的行为。 有问题的平台可能需要使用锁来实现部分或全部std::atomic内容。 因此, std::atomic<T*>可能包括其他成员,而UB意味着您的程序崩溃时,则是reinterpret_cast<std::atomic<T*>*>

  ask by KnowItAllWannabe translate from so

未解决问题?本站智能推荐: