面试官: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 面试题讲解视频

38e9b387635a49932858a17d1d989bf3.jpeg

434618f7d3a0b7c57e726de2d74e3278.png

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值