原文作者:xiaoxlm
使goroutine同步的方法总结
前言:
在前面并发性能对比的文章中,我们可以看到Golang处理大并发的能力十分强劲,而且开发也特别方便,只需要用go关键字即可开启一个新的协程。
但当多个goroutine同时进行处理的时候,就会遇到同时抢占一个资源的情况(并发都会遇到的问题),所以我们希望某个goroutine等待另一个goroutine处理完某一个步骤之后才能继续。sync包就是为了让goroutine同步而出现的。当然还可以使用channel实现,这个后面会介绍到。
锁:
锁有两种:互斥锁(mutex)和读写锁(RWMutex)
互斥锁: 当数据被加锁了之后,除次外的其他协程不能对数据进行读操作和写操作。 这个当然能解决并发程序对资源的操作。但是,效率上是个问题,因为当加锁后,其他协程只有等到解锁后才能对数据进行读写操作。
读写锁: 读数据的时候上读锁,写数据的时候上写锁。有写锁的时候,数据不可读不可写。有读锁的时候,数据可读,不可写。
两种锁的使用方式相同,这里就只列出互斥锁的代码:
Once:
有的时候,我们启动多个相同goroutine,但是里面的某个操作我只希望被执行一次,这个时候Once就上场了。
WaitGroup:
当某个操作或是某个goroutine需要等待一批goroutine执行完毕以后才继续执行,那么这种多线程(go里面说的线程就是goroutine)等待的问题就可以使用WaitGroup了。
代码如下:
Cond:
sync.Cond是用来控制某个条件下,goroutine进入等待时期,等待信号到来,然后重新启动。
代码如下:
上面代码有几个要点要特别说明一下:
1. 每个Cond都必须有个与之关联的锁 // 见第9行
2. 协程方法里面一开始/结束都必须加/解锁 // 见第12行和16行
3. cond.Wait()时会自动解锁,当被唤醒时,又会加上锁。所以第2点提到必须加/解锁。
Channel
channel不仅可以用来goroutine之间的通信,也可以使goroutine同步完成协作。这点主要基于从channel取数据的时候,会阻塞当前goroutine这个特性。示例代码如下:
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。
Golang语言社区
游戏服务器架构丨分布式技术丨大数据丨游戏算法学习
领取专属 10元无门槛券
私享最新 技术干货