client-go和golang源码中的技巧
文章插图
client-go中有很多比较有意思的实现 , 如定时器 , 同步机制等 , 可以作为移植使用 。 下面就遇到的一些技术讲解 , 首先看第一个:
- sets.String(k8s.io/apimachinery/pkg/util/sets/string.go)
ps:更多功能参见源码
package mainimport ("fmt""k8s.io/apimachinery/pkg/util/sets")func main(){map1 := map[string]int{"aaa":1,"bbb":2,"ccc":3}map2 := map[string]int{"ccc":1,"ddd":2,"eee":3}newmap1 := sets.StringKeySet(map1)newmap2 := sets.StringKeySet(map2)fmt.Println(newmap1.List(),newmap2.List())fmt.Println(newmap1.HasAny(newmap2.List()...)) //3个点用于把数组打散为单个元素}结果:true- 同步机制sync.Mutex(golang 内置方法) , 用于数据同步
func (m *Mutex) Lock()func (m *Mutex) Unlock()类似C语言线程的互斥锁 , 用于对数据进行加解锁操作 。 当数据被加锁后 , 未获得该锁的程序将无法读取被加锁的数据 。 从下面例子可以看出在数据被解锁前其他协程无法对该数据进行读写操作 。ps: read data的数据也可能为“data”
【client-go和golang源码中的技巧】
package mainimport ("fmt""sync")type LockTest struct {l sync.Mutexdata string}func main(){lockTest := LockTest{sync.Mutex{},"data"}go func() {lockTest.l.Lock()fmt.Println("sleep begin")time.Sleep(time.Second*2)fmt.Println("sleep end")lockTest.l.Unlock()}()time.Sleep(time.Second*1)go func() {lockTest.l.Lock()fmt.Println("read data:",lockTest.data)lockTest.l.Unlock()}()go func() {lockTest.l.Lock()fmt.Println("write data begin")lockTest.data="http://kandian.youth.cn/index/new data"fmt.Println("write data end")lockTest.l.Unlock()}()time.Sleep(time.Second*5)}结果:sleep beginsleep endwrite data beginwrite data endread data: new data- sync.RWMutex(golang 内置方法) , 用于数据同步
func (rw *RWMutex) RLock()func (rw *RWMutex) RUnlock()func (rw *RWMutex) Lock()func (rw *RWMutex) Unlock()读写锁一般是读锁和写锁结合使用的 。 在有写锁的时候 , 读锁会被阻塞 , 等待写锁释放后才能进行读操作 。ps:sync.Mutex和sync.RWMutex一般都是内置在结构体中使用 , 用于保护本结构体的数据
package mainimport ("fmt""sync")type LockTest struct {l sync.RWMutexdata string}func main(){lockTest := LockTest{sync.RWMutex{},"data"}go func() {lockTest.l.Lock()fmt.Println("write data begin")lockTest.data="http://kandian.youth.cn/index/new data"time.Sleep(time.Second*3)fmt.Println("write data end")lockTest.l.Unlock()}()time.Sleep(time.Second*1)go func() {lockTest.l.RLock()//阻塞等待写锁释放fmt.Println("read begin")fmt.Println("read data:",lockTest.data)fmt.Println("read begin")lockTest.l.RUnlock()}()time.Sleep(time.Second*5)}结果:write data beginwrite data endread beginread data: new dataread begin- sync.Cond(golang 内置方法) , 用于条件变量
func (c *Cond) Wait() func (c *Cond) Signal()func (c *Cond) Broadcast() 官方推荐的典型用法如下 。 由于唤醒协程并不意味着条件已就绪 , 因此在唤醒后需要检测是否本协程的条件已经满足 。c.L.Lock()for !condition() {c.Wait()}... make use of condition ...c.L.Unlock()使用Signal()唤醒的方式如下 , Signal()用于当次唤醒一个协程 。 如果注释掉下例中的Signal() , 那么两个协程会一直Wait() , 并不会继续执行 。package mainimport ("fmt""sync")func main(){l := sync.Mutex{}c := sync.NewCond( i < 10; i++ {go func(i int) {defer wg.Done()fmt.Print(i, " ")}(i)}wg.Wait()}结果:9 4 0 1 2 3 6 5 7 8 - 协程间使用chan进行同步
ps:使用chan进行协程同步一般将chan作为入参传入 , 或在函数内部实现协程间的同步 。 为方便验证 , 下面例子将所有chan作为全局变量
- 中国|浅谈5G移动通信技术的前世和今生
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 桌面|日常使用的软件及网站分享 篇一:几个动态壁纸软件和静态壁纸网站:助你美化你的桌面
- 二维码|村网通?澳大利亚一州推出疫情追踪二维码 还考虑采用人脸识别和地理定位
- 不到|苹果赚了多少?iPhone12成本不到2500元,华为和小米的利润呢?
- 机器人|网络里面的假消息忽悠了非常多的小喷子和小机器人
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 花15.5亿元与中粮包装握手言和 加多宝离上市又进一步?|15楼财经 | 清远加多宝
- 和谐|人民日报海外版今日聚焦云南西双版纳 看科技如何助力人象和谐
- 内容|浅谈内容行业的一些规律和壁垒,聊聊电商平台孵化小红书难点(外部原因)
