GOLANG sync.Mutex和sync.RWMutex
Package synctypeMutexA Mutex is a mutual exclusion lock. Mutexes can be created as part of other structures; the zero value for a Mutex is an unlocked mutex. A Mutex must not be copied after first use. type Mutex struct {
// contains filtered or unexported fields
} Mutex是最简单的一种锁类型,同时也比较粗暴,当一个goroutine获得了Mutex后,其他goroutine只能乖乖等待这个goroutine释放该Mutex.
func (*Mutex)Lockfunc (m *Mutex) Lock() Lock locks m. If the lock is already in use,the calling goroutine blocks until the mutex is available. func (*Mutex)UnlockMutex) Unlock() Unlock unlocks m. It is a run-time error if m is not locked on entry to Unlock. A locked Mutex is not associated with a particular goroutine. It is allowed for one goroutine to lock a Mutex and then arrange for another goroutine to unlock it. 通过调用Lock()方法对Mutex上锁,通过调用Unlock对Mutex解锁。
e.g. 演示Mutex的简单粗暴:任何时刻,只能有一个goroutine获得该Mutex
package main import "fmt" import "time" import "sync" var mutex sync.Mutex func f1(wg *sync.WaitGroup) { mutex.Lock() fmt.Println("goroutine f1 got mutex") for i := 1; i <= 10; i++ { fmt.Print(".")
time.Sleep(1e9)
} fmt.Println("ngoroutine f1 released mutex") mutex.Unlock() wg.Done() } func f2(wg *sync.WaitGroup) { mutex.Lock() fmt.Println("goroutine f2 got mutex") for i := 1; i <= 10; i++ { fmt.Print(".")
time.Sleep(1e9)
} fmt.Println("ngoroutine f2 released mutex") mutex.Unlock() wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2)
go f1(&wg) go f2(&wg) wg.Wait() fmt.Println("the main function ended.") }运行: C:/go/bin/go.exe run test.go [E:/project/go/lx/src] goroutine f2 got mutex .......... goroutine f2 released mutex goroutine f1 got mutex .......... goroutine f1 released mutex the main function ended. 成功: 进程退出代码 0.
通过上面的运行结果可以看出,一个goroutine获得了Mutex后,其他goroutine必须等待该goroutine释放了Mutex后,才能获取Mutex。
typeRWMutexAn RWMutex is a reader/writer mutual exclusion lock. The lock can be held by an arbitrary number of readers or a single writer. RWMutexes can be created as part of other structures; the zero value for a RWMutex is an unlocked mutex.
An RWMutex must not be copied after first use.
func (*RWMutex)func (rw *RWMutex) Lock()Lock locks rw for writing. If the lock is already locked for reading or writing,Lock blocks until the lock is available. func (*RWMutex)RLockRWMutex) RLock() RLock locks rw for reading. func (*RWMutex)RUnlockRWMutex) RUnlock() RUnlock undoes a single RLock call; it does not affect other simultaneous readers. It is a run-time error if rw is not locked for reading on entry to RUnlock. func (*RWMutex)RWMutex) Unlock()Unlock unlocks rw for writing. It is a run-time error if rw is not locked for writing on entry to Unlock. As with Mutexes,a locked RWMutex is not associated with a particular goroutine. One goroutine may RLock (Lock) an RWMutex and then arrange for another goroutine to RUnlock (Unlock) it. RWMutex是一种读写锁,在读锁占用的情况下,会阻止写,但不阻止读,也就是多个goroutine可同时获取读锁;在写锁被占用的情况下,会阻止任何其他的goroutine进来(不论读和写),相当于整个锁由该goroutine独占。
e.g.演示RWMutex可以被上N次读锁
package main import "fmt" import "time" import "sync" var rwmutex sync.RWMutex func f1(wg *sync.WaitGroup) { rwmutex.RLock() fmt.Println("goroutine f1 got read lock") for i := 1; i <= 10; i++ { fmt.Print("f1")
time.Sleep(1e9)
} fmt.Println("ngoroutine f1 released read lock") rwmutex.RUnlock() wg.Done() } func f2(wg *sync.WaitGroup) { rwmutex.RLock() fmt.Println("goroutine f2 got read lock") for i := 1; i <= 10; i++ { fmt.Print("f2")
time.Sleep(1e9)
} fmt.Println("ngoroutine f2 released read lock") rwmutex.RUnlock() wg.Done() } func main() { var wg sync.WaitGroup wg.Add(2)
go f1(&wg) go f2(&wg) wg.Wait() fmt.Println("the main function ended") }运行: C:/go/bin/go.exe run test2.go [E:/project/go/lx/src] goroutine f2 got read lock goroutine f1 got read lock f1f2f1f2f1f2f2f1f1f2f2f1f1f2f2f1f1f2f2f1 goroutine f1 released read lock
goroutine f2 released read lock the main function ended 成功: 进程退出代码 0. e.g.演示RWMutex读锁和写锁相互排斥(本例写上写锁) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |