大家好我是小西,从今天开始,我将开始更新Go基础篇的笔记
预计有5篇,基础篇写完了,再写应用篇,大致是这个计划
老手可以回顾回顾 ,温故知新~ 新手可以收藏一下 做个参考
今天更新第五篇,内容是 Go 并发 select 与 Mutex 锁
上篇我们讲了 Go routine 和 channel 的使用,这篇继续Go并发之旅,这也是Go 中的关键特性
Select 的基本用法
我们在 select中的一个分支中向 c发送数据,另个分支从 quitchannel 中接收数据, 让fibonacci函数可以同时处理多个 channel
这里有几个注意事项
- select 通常和 for配合使用,出现在 for 内部
- select 内部的case 是用来发送和接收 channel 如 c <- x:,<-quit ,v := <-ch , 不要写其它内容
- select 会随机选择一个不阻塞的子句执行,如果都阻塞会进入default分支
default 分支
这里使用了两个go 内部的只读 channel 分别是 tick 和boom防止你向 tick 和 boom 中写数据,他们是只读的。再把他们放的 for 包围的 select 语句中,就可以让你的代码以固定的周期来运行了, 如果在一次 select 中 两个case 都没有数据发送过来,会执行 default 子句二叉树小练习
现在有一样的一个结构,他在Go 中使用下面的结构来表示
type Tree struct {Left*TreeValue intRight *Tree
}
题目要求实现 Walk 和 Same 两个函数,一个实现二叉树的遍历 一个实现对比 Same 如果两棵树相同就返回 true
先思考一分钟
OK, 以下是参考答案:
Walk 函数很好理解,把 .Value 发给 channel 就行了,再递归调用Walk 遍历左边和右边
注意一个channel 惯用法,Walk 接收一个 channel 参数,我把一般把他放在 go routine 中调用,使用channel来通信,在主线程中接收 channel 的数据
Same 函数分别遍历了 t1, t2并在 for 循环中逐个做了对比,不相等则返回false , 直到结束遍历对返回 true
sync.Mutex互斥锁
Go 中推荐使用通信来共享内存。比如,把某个函数 A 放到 go routine 中,再通过channel 来接收他的返回。
有时我不需要向函数外传递数据,只是很让多个go routine 读写同一个变量,这时就是发生竞态条件,导致数据错乱,这时我们需要引入一把锁来管理变量的访问,只有一个 go routine 操作结束后,释放锁,另个 go routine 再上获得资源访问权,这就是互斥锁的用法
总结:
本次我们讲了 Go 中的 select 和 for 的配合使用 , default 分支,完成了二叉树的遍历和对比。了解了不使用 channel 时,借助 sync.Mutex 来管理 go routune 对资源的访问。
这就是Go为我们提供的并发编程的解决方案,这只是有一小部分。下期我们继续,讲读写锁 RWMutex 和 WaitGroup以及 Context , 下期见