gpt4 book ai didi

c++ - 使用 atomic 的简单自旋锁中的数据竞争

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:21 26 4
gpt4 key购买 nike

<分区>

#include<atomic>
#include<thread>
#include<vector>
#include<iostream>
#include<algorithm>
#include<mutex>

using namespace std;

class spinlock
{
private:
atomic<bool> flag;
public:
spinlock():flag(false)
{
}

void lock()
{
bool temp=false;
while(!flag.compare_exchange_weak(temp, true, std::memory_order_seq_cst) && !temp);
}

void unlock()
{
flag.store(false, std::memory_order_seq_cst);
}
};

int main()
{
spinlock sp;
//mutex sp;
std::vector<std::thread> threads;
int count=0;
std::cout << "increase global counter with 10 threads...\n";
for (int i=1; i<=10000; ++i)
{
threads.push_back(std::thread([&sp,&count](){for(int i=0;i<10;++i){sp.lock();++count;sp.unlock();}}));
}

for_each(threads.begin(),threads.end(),[](thread &t){t.join();});

cout<<count<<endl;
return 0;
}

上面的代码创建了 10k 个线程并使用它们来递增计数器。我在带有 gcc 5.2 的 x86_64 机器上运行它,我尝试了具有不同内存顺序和 compare_exchange_weak/strong 的代码。他们都没有给出 100k 的预期结果。当我用互斥执行同样的实验时,我得到了正确的结果。如果 atomic 确实是 atomic 并且内存排序 seq_cst 是我在这里使用的最强可用,为什么我在这里得不到正确的结果?

编辑(更正代码):

void lock()
{
bool temp=false;
while(!flag.compare_exchange_weak(temp, true, std::memory_order_seq_cst))
{
temp=false;
}
}

问题是因为临时变量更新失败的虚假唤醒,但由于用新值复制了临时变量,函数返回。因此在计数器中重置它的预期值。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com