为什么这个自旋锁需要 memory_order_acquire_release 而不是仅仅获取?
Why does this spinlock require memory_order_acquire_release instead of just acquire?
// spinlockAcquireRelease.cpp
#include <atomic>
#include <thread>
class Spinlock{
std::atomic_flag flag;
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while(flag.test_and_set(std::memory_order_acquire) ); // line 12
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
Spinlock spin;
void workOnResource(){
spin.lock();
// shared resource
spin.unlock();
}
int main(){
std::thread t(workOnResource);
std::thread t2(workOnResource);
t.join();
t2.join();
}
在注释中是这样写的:
In case more than two threads use the spinlock, the acquire semantic of the lock method is not sufficient. Now the lock method is an acquire-release operation. So the memory model in line 12 [the call to flag.test_and_set(std::memory_order_acquire)
] has to be changed to std::memory_order_acq_rel
.
为什么这个自旋锁只适用于 2 个线程而不适用于超过 2 个线程?导致此自旋锁出错的示例代码是什么?
来源:https://www.modernescpp.com/index.php/acquire-release-semantic
std::memory_order_acq_rel
不是必需的。
Mutex 同步在 2 个线程之间..一个释放数据,另一个获取数据。
因此,其他线程执行释放或获取操作是无关紧要的。
如果获取由独立的栅栏处理,也许会更直观(也更有效):
void lock(){
while(flag.test_and_set(std::memory_order_relaxed) )
;
std::atomic_thread_fence(std::memory_order_acquire);
}
void unlock(){
flag.clear(std::memory_order_release);
}
多个线程可以在 flag.test_and_set
上旋转,
但是有人设法读取更新的值并再次设置它(在单个操作中)..只有那个线程在 while 循环之后获取受保护的数据。
// spinlockAcquireRelease.cpp
#include <atomic>
#include <thread>
class Spinlock{
std::atomic_flag flag;
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while(flag.test_and_set(std::memory_order_acquire) ); // line 12
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
Spinlock spin;
void workOnResource(){
spin.lock();
// shared resource
spin.unlock();
}
int main(){
std::thread t(workOnResource);
std::thread t2(workOnResource);
t.join();
t2.join();
}
在注释中是这样写的:
In case more than two threads use the spinlock, the acquire semantic of the lock method is not sufficient. Now the lock method is an acquire-release operation. So the memory model in line 12 [the call to
flag.test_and_set(std::memory_order_acquire)
] has to be changed tostd::memory_order_acq_rel
.
为什么这个自旋锁只适用于 2 个线程而不适用于超过 2 个线程?导致此自旋锁出错的示例代码是什么?
来源:https://www.modernescpp.com/index.php/acquire-release-semantic
std::memory_order_acq_rel
不是必需的。
Mutex 同步在 2 个线程之间..一个释放数据,另一个获取数据。
因此,其他线程执行释放或获取操作是无关紧要的。
如果获取由独立的栅栏处理,也许会更直观(也更有效):
void lock(){
while(flag.test_and_set(std::memory_order_relaxed) )
;
std::atomic_thread_fence(std::memory_order_acquire);
}
void unlock(){
flag.clear(std::memory_order_release);
}
多个线程可以在 flag.test_and_set
上旋转,
但是有人设法读取更新的值并再次设置它(在单个操作中)..只有那个线程在 while 循环之后获取受保护的数据。