Go 快速入门指南 – 互斥锁和定时器

互斥锁 对于任一共享资源,同一时间保证只有一个操作者,这种方法称为 互斥机制。 关键字 Mutex 表示互斥锁类型,它的 Lock 方法用于获取锁,Unlock 方法用于释放锁。在 Lock 和 Unlock 之间的代码,可以读取和修改共享资源,这部分区域称为 临界区。 错误的并发操作 先来看一个错 …

对于任一共享资源,同一时间保证只有一个操作者,这种方法称为互斥机制

关键字Mutex表示互斥锁类型,它的Lock方法用于获取锁,Unlock方法用于释放锁。在LockUnlock之间的代码,可以读取和修改共享资源,这部分区域称为临界区

先来看一个错误的示例。

在Map小节中讲到,Map不是并发安全的,也就是说,如果在多个线程中,同时对一个 Map 进行读写,会报错。现在来验证一下, 通过启动100 个 goroutine来模拟并发调用,每个 goroutine 都对 Map 的 key 进行设置。

packagemain
import"sync"
funcmain(){
m:=make(map[int]bool)
varwgsync.WaitGroup
forj:=0;j

通过输出信息fatal error: concurrent map writes可以看到,并发写入 Map 确实会报错。

Map 并发写入如何正确地实现呢?

一种简单的方案是在并发临界区域 (也就是设置 Map key 的地方) 进行加互斥锁操作,互斥锁保证了同一时刻 只有一个 goroutine 获得锁,其他 goroutine 全部处于等待状态,这样就把并发写入变成了串行写入, 从而消除了报错问题。

packagemain
import(
"fmt"
"sync"
)
funcmain(){
varmusync.Mutex
m:=make(map[int]bool)
varwgsync.WaitGroup
forj:=0;j

利用channel (通道)time.After()方法实现超时控制。

packagemain
import(
"fmt"
"time"
)
funcmain(){
ch:=make(chanbool)
gofunc(){
deferfunc(){
ch

调用time.NewTicker方法即可。

packagemain
import(
"fmt"
"time"
)
funcmain(){
ticker:=time.NewTicker(time.Second)
deferticker.Stop()
done:=make(chanbool)
gofunc(){
time.Sleep(5*time.Second)//模拟耗时操作
done
  1. 1.互斥锁 – 维基百科 (https://zh.wikipedia.org/wiki/互斥锁)

  2. 2.临界区 – 百度百科 (https://baike.baidu.com/item/临界区/8942134)

联系我

Go 快速入门指南 - 互斥锁和定时器

声明:本站所有文章,如无特殊说明或标注,均为爬虫抓取以及网友投稿,版权归原作者所有。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容