没看懂为什么lock函数要使用Acquire,将swap变成compare_exchange_weak同理 不是acquire-load/release-store吗?
pub fn lock(&self) {
while self.locked.swap(true, Acquire) {
std::hint::spin_loop();
}
}
Ext Link: https://marabos.nl/atomics/building-spinlock.html
1
共 4 条评论, 1 页
评论区
写评论对的对的,前面对
failure参数描述错了,使用了success=Acquire读之后,compare_exchange_weak(&self, current, new, success, failure)里的写已经默认是Relaxed了,第二个排序参数是失败时的设置,不过也不影响读写屏障的使用逻辑。这里设置
failure=Relaxed,是因为它控制的是返回值里Err(new_val)的load顺序(返回的新值),但是我们的lock不需要读取这个新值,只是判断是否成功,而我们只等待交换成功的操作,所以不成功时Relaxed就可以了。如果在更复杂场景下,交换失败后,需要获取最新值做其他处理,这时候failure可能需要更严格的顺序要求--
👇
iamazy: compare_exchange_weak 中的
Relaxed不是设置失败时使用的排序吗--
👇
xiaoyaou: 这个感觉不太好用什么方式解释,专业角度里的一堆术语“happens-before”之类的同步关系更是抽象的一。
按我个人理解简单点说就是,
SpinLock是为了在lock<--临界区-->unlock之间建立一个同步关系,为了防止因为指令重排序,让原本临界区的代码,被排序到临界区外面去了(lock之前,或者unlock之后)。为了保护临界区,所以加锁时(
lock)需要保证后面的指令不会被排序到前面,也就是需要一个读屏障;而解锁时(unlock)需要保证前面的指令不会被排序到后面,也就是需要一个写屏障。不管是用
swap实现的加锁,还是compare_exchange_weak实现的,在进入临界区都只需要一个读屏障就够了,即Acquire序。所以compare_exchange_weak里的写操作使用最宽松的Relaxed也是够的,无关紧要,外面的代码是否能重排序到临界区不影响临界区逻辑正确性。compare_exchange_weak 中的
Relaxed不是设置失败时使用的排序吗--
👇
xiaoyaou: 这个感觉不太好用什么方式解释,专业角度里的一堆术语“happens-before”之类的同步关系更是抽象的一。
按我个人理解简单点说就是,
SpinLock是为了在lock<--临界区-->unlock之间建立一个同步关系,为了防止因为指令重排序,让原本临界区的代码,被排序到临界区外面去了(lock之前,或者unlock之后)。为了保护临界区,所以加锁时(
lock)需要保证后面的指令不会被排序到前面,也就是需要一个读屏障;而解锁时(unlock)需要保证前面的指令不会被排序到后面,也就是需要一个写屏障。不管是用
swap实现的加锁,还是compare_exchange_weak实现的,在进入临界区都只需要一个读屏障就够了,即Acquire序。所以compare_exchange_weak里的写操作使用最宽松的Relaxed也是够的,无关紧要,外面的代码是否能重排序到临界区不影响临界区逻辑正确性。因为
Release的store和Acquire的load建立同步关系,所以swap的load部分必须使用Acuqire和已经获取锁的unlock的Release store建立同步,从而让这两个前后锁所保护的临界区有happen-before关系这个感觉不太好用什么方式解释,专业角度里的一堆术语“happens-before”之类的同步关系更是抽象的一。
按我个人理解简单点说就是,
SpinLock是为了在lock<--临界区-->unlock之间建立一个同步关系,为了防止因为指令重排序,让原本临界区的代码,被排序到临界区外面去了(lock之前,或者unlock之后)。为了保护临界区,所以加锁时(
lock)需要保证后面的指令不会被排序到前面,也就是需要一个读屏障;而解锁时(unlock)需要保证前面的指令不会被排序到后面,也就是需要一个写屏障。不管是用
swap实现的加锁,还是compare_exchange_weak实现的,在进入临界区都只需要一个读屏障就够了,即Acquire序。所以compare_exchange_weak里的写操作使用最宽松的Relaxed也是够的,无关紧要,外面的代码是否能重排序到临界区不影响临界区逻辑正确性。