type Mutexhtml
func (rw *RWMutex) Unlock()golang
其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不肯定场景,即读写次数没有明显的区别,而且只容许只有一个读或者写的场景,因此该锁叶叫作全局锁.atom
func (m *Mutex) Unlock()用于解锁m,若是在使用Unlock()前未加锁,就会引发一个运行错误.spa
已经锁定的Mutex并不与特定的goroutine相关联,这样能够利用一个goroutine对其加锁,再利用其余goroutine对其解锁.code
正常运行例子:htm
package main import ( "fmt" "sync" ) func main() { var l *sync.Mutex l = new(sync.Mutex) l.Lock() defer l.Unlock() fmt.Println("1") } 结果输出:1
package main import ( "fmt" "sync" ) func main() { var l *sync.Mutex l = new(sync.Mutex) l.Unlock() fmt.Println("1") l.Lock() } 运行结果: panic: sync: unlock of unlocked mutex
当在解锁以前再次进行加锁,便会死锁状态源码
package main import ( "fmt" "sync" ) func main() { var l *sync.Mutex l = new(sync.Mutex) l.Lock() fmt.Println("1") l.Lock() } 运行结果: 1 fatal error: all goroutines are asleep - deadlock!
RWMutex是一个读写锁,该锁能够加多个读锁或者一个写锁,其常常用于读次数远远多于写次数的场景.
it
func (rw *RWMutex) Lock() 写锁,若是在添加写锁以前已经有其余的读锁和写锁,则lock就会阻塞直到该锁可用,为确保该锁最终可用,已阻塞的 Lock 调用会从得到的锁中排除新的读取器,即写锁权限高于读锁,有写锁时优先进行写锁定
func (rw *RWMutex) Unlock() 写锁解锁,若是没有进行写锁定,则就会引发一个运行时错误.ast
package main import ( "fmt" "sync" ) func main() { var l *sync.RWMutex l = new(sync.RWMutex) l.Unlock() fmt.Println("1") l.Lock() } 运行结果:panic: sync: unlock of unlocked mutex
func (rw *RWMutex) RLock() 读锁,当有写锁时,没法加载读锁,当只有读锁或者没有锁时,能够加载读锁,读锁能够加载多个,因此适用于"读多写少"的场景class
func (rw *RWMutex)RUnlock() 读锁解锁,RUnlock 撤销单次 RLock 调用,它对于其它同时存在的读取器则没有效果。若 rw 并无为读取而锁定,调用 RUnlock 就会引起一个运行时错误(注:这种说法在go1.3版本中是不对的,例以下面这个例子)。
package main import ( "fmt" "sync" ) func main() { var l *sync.RWMutex l = new(sync.RWMutex) l.RUnlock() //1个RUnLock fmt.Println("1") l.RLock() } 运行结果:1 可是程序中先尝试 解锁读锁,而后才加读锁,可是没有报错,而且可以正常输出.
分析:go1.3版本中出现这种状况的缘由分析,经过阅读源码能够很清晰的获得结果
func (rw *RWMutex) RUnlock() { if raceenabled { _ = rw.w.state raceReleaseMerge(unsafe.Pointer(&rw.writerSem)) raceDisable() }<span style="color:#FF0000;"> if atomic.AddInt32(&rw.readerCount, -1) < 0 { //readercounter初始值为0,调用RUnLock以后变为-1,继续往下执行 // A writer is pending. if atomic.AddInt32(&rw.readerWait, -1) == 0 { //此时readerwaiter变为1,1-1以后变为0,能够继续之后的操做.</span> // The last reader unblocks the writer. runtime_Semrelease(&rw.writerSem) } } if raceenabled { raceEnable() } }
当RUnlock多于RLock多个时,便会报错,进入死锁.实例以下:
package main import ( "fmt" "sync" ) type s struct { readerCount int32 } func main() { l := new(sync.RWMutex) l.RUnlock() l.RUnlock() //此处出现死锁 fmt.Println("1") l.RLock() } 运行结果: 1 fatal error: all goroutines are asleep - deadlock!
总结:
因此在go1.3版本中,运行过程当中容许RUnLock早于RLock一个,也只能早于1个(注:虽然代码容许,可是强烈不推荐使用),而且在早于以后必须利用RLock进行加锁才能够继续使用.