go 互斥锁与读写锁
go 互斥锁与读写锁
互斥锁
互斥锁控制下的多个写操作之间、多个读操作之间是互斥的,并且写操作与读操作之间也是互斥的。
互斥锁适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁,也就是完全互斥。
互斥锁是传统的并发程序对共享资源进行访问控制的主要手段。它由标准库代码包sync中的Mutex结构体类型代表。sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开方法――Lock和Unlock。顾名思义,前者被用于锁定当前的互斥量,而后者则被用来对当前的互斥量进行解锁。
使用方法
var mutex sync.Mutex func write() { mutex.Lock() //加互斥锁 defer mutex.Unlock() //解互斥锁 // 省略若干条语句 }
使用建议
- 互斥锁的成对的锁定和解锁应该成对出现(虽然互斥锁可以被直接的在多个Goroutine之间共享)。
- 把互斥锁作为某一个结构体类型中的字段,以便在该类型的多个方法中使用它。
- 我们还应该使代表互斥锁的变量的访问权限尽量的低。这样才能尽量避免它在不相关的流程中被误用,从而导致程序不正确的行为。
- 习惯使用defer,defer语句保证了在该函数被执行结束之前互斥锁mutex一定会被解锁。
读写锁
读写锁即是针对于读写操作的互斥锁。它与普通的互斥锁最大的不同就是,它可以分别针对读操作和写操作进行锁定和解锁操作。
也就是说,读写锁控制下的多个写操作之间都是互斥的,并且写操作与读操作之间也都是互斥的。但是,多个读操作之间却不存在互斥关系。
使用方法
var mutex sync.RWMutex func write() { mutex.RLock() //加读写锁 defer mutex.RUnlock() //解读写锁 // 省略若干条语句 }