【发布时间】:2017-06-23 03:56:00
【问题描述】:
我用 C++11 原子库实现了一个自旋锁:
class SpinLock {
atomic_bool latch_;
public:
SpinLock() :latch_(false){
}
void lock() {
while(tryLock() == false);
}
bool tryLock() {
bool b = false;
return latch_.compare_exchange_weak(b,true,std::memory_order_relaxed);
}
void unlock() {
latch_.store(false,std::memory_order_relaxed);
}
};
我通过产生多个线程来测试正确性如下:
static int z = 0;
static SpinLock spinLock;
static void safeIncrement(int run) {
while(--run >= 0) {
std::lock_guard<SpinLock> guard(spinLock);
++z;
}
}
static void test(int nThreads =2) {
std::vector<std::thread*> workers(nThreads);
z = 0;
for(auto& ptr : workers) ptr = new std::thread(safeIncrement,1<<20);
for(auto ptr : workers) ptr->join();
cout<<"after increment: " <<z << " out of " << (1<<20) * nThreads<<endl;
for(auto ptr : workers) delete ptr;
}
int main() {
test(4);
return 0;
}
令我感到惊讶的是,最后的总数加起来是一个正确的值,顺序宽松。通过这篇文章:http://en.cppreference.com/w/cpp/atomic/memory_order,宽松的顺序意味着“没有同步或排序约束”,所以一个线程的更改并不意味着其他线程可以看到,对吧?为什么还是正确的?
(测试在 Intel(R) Core(TM) i5-3337U CPU @ 1.80GHz 上运行)
编辑:(感谢 Maxim 的评论)更新了代码:初始化 SpinLock 中的数据成员,并更新了测试代码。
【问题讨论】:
-
提供完整的测试源代码。
-
SpinLock::latch_没有初始化,初始值不确定。 -
这具体是一个 C++11 问题吗?
标签: multithreading c++11 atomic memory-barriers spinlock