请用golang编写一个自旋锁并解释代码
下面是一个使用golang编写的简单自旋锁的示例代码:
package main
import (
"fmt"
"runtime"
"sync/atomic"
"time"
)
type SpinLock struct {
flag int32
}
func (l *SpinLock) Lock() {
for !atomic.CompareAndSwapInt32(&l.flag, 0, 1) {
runtime.Gosched() // 让出CPU时间片给其他goroutine
}
}
func (l *SpinLock) Unlock() {
atomic.StoreInt32(&l.flag, 0)
}
func main() {
lock := &SpinLock{}
go func() {
lock.Lock()
fmt.Println("Goroutine 1: Acquired lock")
time.Sleep(2 * time.Second)
lock.Unlock()
fmt.Println("Goroutine 1: Released lock")
}()
go func() {
lock.Lock()
fmt.Println("Goroutine 2: Acquired lock")
time.Sleep(2 * time.Second)
lock.Unlock()
fmt.Println("Goroutine 2: Released lock")
}()
time.Sleep(5 * time.Second)
}
这个自旋锁使用一个int32类型的flag来表示锁的状态,0表示未锁定,1表示已锁定。
在Lock()方法中,使用原子操作atomic.CompareAndSwapInt32()尝试将flag从0设置为1,如果设置成功(即返回true),则表示获取到了锁;否则继续循环自旋等待。
在Unlock()方法中,使用原子操作atomic.StoreInt32()将flag设置为0,表示释放锁。
示例代码中创建了两个goroutine,分别尝试获取自旋锁并进行一些操作。通过设置适当的休眠时间,可以观察到goroutine之间交替获取和释放锁的过程。
需要注意的是,自旋锁适用于短时间的临界区,如果临界区较长,使用自旋锁可能会导致性能下降,因为自旋锁会占用CPU资源。在实际使用中,需要根据具体情况选择合适的锁机制
原文地址: https://www.cveoy.top/t/topic/iqcw 著作权归作者所有。请勿转载和采集!