GO语言培训之什么是互斥锁?
作者:IT科技类资讯 来源:域名 浏览: 【大中小】 发布时间:2025-11-04 00:19:48 评论数:
Go语言的培训sync包中实现了两种锁 Mutex (互斥锁)和 RWMutex (读写锁),其中 RWMutex 是互斥基于 Mutex 实现的,只读锁的培训实现使用类似引用计数器的功能。
互斥锁

Mutex 是互斥互斥锁,有 Lock()加锁、培训Unlock()解锁两个方法,互斥使用Lock()加锁后,培训便不能再次对其进行加锁,互斥直到利用 Unlock()解锁对其解锁后才能再次加锁。培训适用于读写不确定场景,互斥即读写次数没有明显的培训区别,并且只允许只有一个读或者写的b2b供应网互斥场景,所以该锁也叫做全局锁。培训
func (m *Mutex) Lock()Lock方法锁住m,互斥如果m已经加锁,培训则阻塞直到m解锁。
func (m *Mutex) Unlock()Unlock方法解锁m,如果m未加锁会导致运行时错误。锁和线程无关,可以由不同的线程加锁和解锁。
互斥锁应用
只要有两个goroutine并发访问同一变量,且至少其中的一个是写操作的时候就会发生数据竞争。数据竞争会在两个以上的goroutine并发访问相同的变量且至少其中一个为写操作时发生。云服务器提供商
允许多个goroutine访问变量,但是同一时间只允许一个goroutine访问。我们可以用sync包中的Mutex来实现,保证共享变量不会被并发访问。
实例如下:
package main import ( "fmt" "sync" ) var ( m = make(map[int]int) Mlock = new(sync.Mutex) ) func main() { for i := 0; i < 1000; i++ { go func(i int) { // Mlock.Lock() m[i] = i * i // Mlock.Unlock() }(i) } // Mlock.Lock() for k, v := range m { fmt.Printf("%d * %d = %d\n", k, k, v) } // Mlock.Unlock() }运行错误:
fatal error: concurrent map writes将上述代码中的注释打开则程序正常运行。
当Unlock()在Lock()之前使用时便会报错,实例如下:
package main import ( "fmt" "sync" ) func main() { var MLock *sync.Mutex MLock = new(sync.Mutex) MLock.Unlock() fmt.Println("hello Mutex") MLock.Lock() }运行错误:
panic: sync: unlock of unlocked mutex当在解锁之前再次进行加锁,便会死锁状态,实例如下:
package main import ( "fmt" "sync" ) func main() { var MLock *sync.Mutex MLock = new(sync.Mutex) MLock.Lock() fmt.Println("hello Mutex") MLock.Lock() }运行错误:
fatal error: all goroutines are asleep - deadlock!互斥锁只能锁定一次,当在解锁之前再次进行加锁,便会死锁状态,如果在加锁前解锁,便会报错“panic: sync: unlock of unlocked mutex”。
