Go语言中的Mutex| 青训营笔记

66 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天

前言

Go语言中自带的锁位于sync包下,其中实现了互斥锁(Mutex),读写锁(RWMutex)。

为什么需要锁

现在假设有一个商品销售的网站,有两个用户A和B,它们正在同时浏览一件商品,但是这件商品只剩一件了,此时他们同时进行了下单操作,那么这件商品系统究竟判定给谁?

放在现实中,这种情况是很好解决的,因为就剩一件商品,谁先摸到就可以当作是谁的(不算撒泼耍赖的情况下)。拿到手了,即使我不去付款,拿着它到处转悠别人也抢不走,这就相当于上了一个锁。像这种对共享数据进行锁定,保证同一时刻只能有一个线程去操作的锁就叫互斥锁。

Go语言中的互斥锁

在Go语言中,我们可以使用sync.Mutex来声明一个互斥锁。

type Mutex struct {
    state int32 //状态位 
    sema  uint32 //信号量,用来控制等待的goroutine 的阻塞,休眠,唤醒
}

Go语言天然地实现并发操作,所以锁通常是搭配着Goroutines使用。


// 声明一个锁
mu sync.mutex

// 上锁
mu.Lock()

// 一些会访问共享数据的操作

// 解锁
mu.Unlock()

sync.Mutex 的一些注意事项

  • 它的零值是一个未加锁的互斥锁
  • 当这个锁需要被作为参数传递的时候,必须使用指针的形式对其进行传递,否则锁会被拷贝多份,虽然状态一样,但已经不是同一个锁了
  • 上锁是会消耗性能,因此要尽量减少锁持有的时间
  • 锁不能多次上锁,否则会死锁,也不能多次解锁,否则会产生panic错误
  • 要合理使用defer释放锁

若有错误或疏漏,还望海涵,