面试官:Go 如何实现自旋锁?

大家好,我是木川

在Go中实现自旋锁(Spinlock)可以通过使用sync/atomic包中的原子操作来完成。自旋锁是一种非阻塞锁,它不会让线程进入休眠状态,而是反复尝试获取锁,直到成功为止。

一、示例

package main

import (
    "fmt"
    "sync"
    "sync/atomic"
)

type Spinlock struct {
    flag int32 // 使用int32类型的标志位表示锁的状态
}

func (s *Spinlock) Lock() {
    for !atomic.CompareAndSwapInt32(&s.flag, 0, 1) {
        // 自旋,直到成功获取锁
    }
}

func (s *Spinlock) Unlock() {
    atomic.StoreInt32(&s.flag, 0) // 释放锁
}

func main() {
    var wg sync.WaitGroup
    var spinlock Spinlock

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            spinlock.Lock()
            defer spinlock.Unlock()

            // 在这里执行需要互斥访问的操作
            fmt.Printf("Goroutine %d is in the critical section\n", id)
        }(i)
    }

    wg.Wait()
}

在上面的示例中,我们首先定义了一个名为Spinlock的结构体,它包含一个flag字段,用于表示锁的状态。Lock方法使用atomic.CompareAndSwapInt32函数在一个循环中尝试获取锁,直到成功为止。Unlock方法用于释放锁,将flag设置为0。

main函数中,我们创建了5个并发的goroutine,并在每个goroutine中使用spinlock来保护临界区的访问。这确保了在任何给定时刻只有一个goroutine能够进入临界区。

二、总结

需要注意的是,自旋锁适用于短期内锁的竞争不激烈的情况。在高并发的情况下,自旋锁可能会导致CPU资源浪费,因此需要慎重选择是否使用自旋锁,或者考虑其他锁的类型,如互斥锁(sync.Mutex)或读写锁(sync.RWMutex),以更好地满足实际需求。

最后给自己的原创 Go 面试小册打个广告,如果你从事 Go 相关开发,欢迎扫码购买,目前 10 元买断,加下面的微信发送支付截图额外赠送一份自己录制的 Go 面试题讲解视频

面试官:Go 如何实现自旋锁?_第1张图片

面试官:Go 如何实现自旋锁?_第2张图片

如果对你有帮助,帮我点一下在看或转发,欢迎关注我的公众号

你可能感兴趣的:(golang,开发语言,后端)