Golang学习笔记之互斥锁(Mutex)
Go语言包中的sync包提供了两种锁,互斥锁(sync.Mutex)和读写锁(sync.RWMutex)
这一篇博文我们只说一下互斥锁。
Mutex是一个互斥锁,可以创立为其余结构体的字段;零值为解锁状态。Mutex类型的锁和线程无关,可以由不同的线程加锁和解锁。
? 它只有两个公开方法:Lock()加锁,unlock()解锁。
? 在同一个协程中加锁后,不能再继续对其加锁,否则会panic。只有在解锁之后才能再次加锁。
? 只允许只有一个读或者者写的场景
? 在使用Unlock()解锁前,未使用Lock()加锁,就会引起一个运行错误。
函数原型func (m *Mutex) Lock()
Lock方法锁住m,假如m已经加锁,则阻塞直到m解锁。func (m *Mutex) Unlock()
Unlock方法解锁m,假如m未加锁会导致运行时错误。锁和线程无关,可以由不同的线程加锁和解锁。
一个例子了解互斥锁的作用
package mainimport ( "fmt" "sync")var num = 0func increment(wg *sync.WaitGroup) { num = num + 1 wg.Done()}func main() { var w sync.WaitGroup for i := 0; i < 1000; i++ { w.Add(1) //开启协程 go increment(&w) } w.Wait() fmt.Println("num =", num)}在上述程序中,调用1000个协程来进行num=num+1操作
运行几次的输出分别为
num = 971
num = 944
num = 959
每次运行都没有达到预期的效果,由于多个并发的协程试图访问 num 的值,这时就会发生竞态条件。
现在我们可以对上述程序加上锁,每次只能由一个线程来操作num的值
package mainimport ( "fmt" "sync")var num = 0func increment(wg *sync.WaitGroup, m *sync.Mutex) { //互斥锁 m.Lock() //当有线程进去进行加锁 num = num + 1 m.Unlock() //出来后解锁,其余线程才可以进去 wg.Done()}var w sync.WaitGroup var m sync.Mutex for i := 0; i < 1000; i++ { w.Add(1) go increment(&w, &m)//这里要传引用并不能传值,假如传值,那么每个协程都会得到 Mutex 的一份拷贝,竞态条件还是会发生。 } w.Wait() fmt.Println("num =", num)输出
num = 1000
我们也可以使用缓冲信道来实现互斥锁
func increment2(wg *sync.WaitGroup, b chan bool) { //自己设置互斥锁 b <- true num = num + 1 <-b wg.Done()}func main() { var w sync.WaitGroup ch := make(chan bool,1) for i := 0; i < 1000; i++ { w.Add(1) go increment2(&w, ch) } w.Wait() fmt.Println("num =", num)}输出
num = 1000
func main() { wa := sync.WaitGroup{} var mu sync.Mutex fmt.Println("加锁0") mu.Lock() fmt.Printf("上锁中0\t") for i := 1; i < 4; i++ { wa.Add(1) go func(i int) { fmt.Printf("加锁%d\t", i) mu.Lock() fmt.Printf("上锁中%d\t", i) time.Sleep(time.Second * 1) mu.Unlock() fmt.Printf("解锁%d\t", i) wa.Done() }(i) } time.Sleep(time.Second * 5) mu.Unlock() fmt.Println("\n解锁0") wa.Wait()}输出为
加锁0
上锁中0 加锁2 加锁3 加锁1 上锁中2
解锁0
解锁2 上锁中3 解锁3 上锁中1 解锁1
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Golang学习笔记之互斥锁(Mutex)
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Golang学习笔记之互斥锁(Mutex)