【问题标题】:Where is the race?比赛地点在哪里?
【发布时间】:2014-09-02 16:34:40
【问题描述】:
#include <iostream>
#include <atomic>
#include <array>
#include <thread>

template <typename T>
struct node {
    T      value;
    node*  next{nullptr};
};

typedef node<int> node_type;

std::atomic<node_type*> _begin;

node_type* get() {
    node_type* b = _begin;

    while (!_begin.compare_exchange_weak(b, b->next))
        ;

    return b;
}

void give(node_type* v) {
    v->next = _begin;

    while (!_begin.compare_exchange_weak(v->next, v))
        ;
}

void get_and_give() {
    for (int i = 0; i < 1000000; ++i) {
        auto n = get();

        give(n);
    }
}

int main(int argc, const char * argv[])
{
    std::array<node_type, 4> _nodes;

    for (auto & i : _nodes)
        give(&i);

    std::thread t1(get_and_give);
    std::thread t2(get_and_give);
    std::thread t3(get_and_give);

    get_and_give();

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

get 返回的值内的下一个指针存在竞争(我相信)。这不会发生在运行 get_and_give 的 2 个线程上,所以看起来它在其他线程中缺乏顺序一致性,但我所做的一切都是 memory_order_seq_cst,所以我不明白这怎么可能是个问题?

有什么想法吗!?

【问题讨论】:

    标签: c++ multithreading c++11 concurrency atomic


    【解决方案1】:

    我怀疑您遇到了所谓的 ABA 问题。

    来自wikipedia

    ABA 问题发生在同步过程中,当一个位置被读取两次,两次读取的值相同,“值相同”用于表示“没有任何变化”。但是,另一个线程可以在两次读取之间执行并更改值,做其他工作,然后将值改回,从而欺骗第一个线程认为“没有任何变化”,即使第二个线程确实违反了该假设。

    【讨论】:

    • 维基百科上的例子几乎是我的确切代码,所以大概就是这样!
    猜你喜欢
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多