c – 使用原子在简单的自旋锁中进行数据竞争
发布时间:2020-12-16 07:14:17 所属栏目:百科 来源:网络整理
导读:参见英文答案 C++11 Implementation of Spinlock using atomic????????????????????????????????????2个 #includeatomic#includethread#includevector#includeiostream#includealgorithm#includemutexusing namespace std;class spinlock{ private: atomicbo
参见英文答案 >
C++11 Implementation of Spinlock using <atomic>????????????????????????????????????2个
#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个线程并使用它们来递增计数器.我在g86 5.2的x86_64机器上运行它,我尝试了不同内存排序的代码和compare_exchange_weak / strong.他们都没有给出100k的预期结果.当我使用互斥锁执行相同的实验时,我得到了正确的结果.如果原子确实是原子的并且内存排序seq_cst是我在这里使用的最强可用的,为什么我不能得到正确的结果呢? 编辑(更正的代码): void lock() { bool temp=false; while(!flag.compare_exchange_weak(temp,std::memory_order_seq_cst)) { temp=false; } } 问题是由于临时变量更新失败的虚假唤醒,但由于temp被复制为新值,因此函数返回.所以在柜台重置它的期望值. 解决方法
您需要阅读compare_exchange_weak的文档.问题是您需要将temp重新设置为false,因为compare通过比较交换操作将temp写入temp.参见例如
example (mis) use of compare-exchange-weak
在该链接中,还阅读了有关使用暂停指令禁用推测执行的内容. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |