标题:[实践OK]关于go进行多进程通讯的等待子进程问题学习浅显研究。 出处:向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除 时间:Mon, 04 Jan 2021 18:53:29 +0000 作者:jackxiang 地址:https://jackxiang.com/post/10820/ 内容: 背景:有一篇朋友圈说是一个k8s里面Server的Pod销毁上报Zookeeper出现IP地址连接还是原来的,用到了zk的watcher,理论上不应该这样,于是查来查去,其大体意思就是说用了Go的多进程,有一个进程去读取配置了,因为配置还是老的,而用到了Go的多进程,于是文末那代码,我看了下,简单,但不明白,于是顺藤摸瓜学习一下这个rsync的原理。 —————————— #tree -L 2 .|grep go ├── loop.go ├── pipe.go ├── waitgrouppointer.go └── wg.go #cat loop.go package main import ( "fmt" //"time" ) func main(){ for i := 0; i < 100 ; i++{ go fmt.Println(i) } //time.Sleep(time.Second) } 这个说是运行太快,子进程没输出主进程就退了,啥也不输出。 #cat pipe.go package main import ( "fmt" //"time" ) func main() { c := make(chan bool, 100) for i := 0; i < 100; i++ { go func(i int) { fmt.Println(i) c <- true }(i) } for i := 0; i < 100; i++ { <-c } } 这个说是管道要是上万,会耗尽系统管道资源。 #cat waitgroup.go package main import ( "fmt" "sync" //"time" ) func main() { wg := sync.WaitGroup{} wg.Add(100) for i := 0; i < 100; i++ { go func(i int) { fmt.Println(i) wg.Done() }(i) } wg.Wait() } 这个说是挺好的,因为它用到了原子加减法,这里好像C语言也有类似的函数, 再就是说它是用来阻塞方进程的,WaitGroup 对象内部有一个计数器,最初从0开始,它有三个方法:Add(), Done(), Wait() 用来控制计数器的数量。Add(n) 把计数器设置为n ,Done() 每次把计数器-1 ,wait() 会阻塞代码的运行,直到计数器地值减为0。 这里首先把wg 计数设置为100, 每个for循环运行完毕都把计数器减一,主函数中使用Wait() 一直阻塞,直到wg为零——也就是所有的100个for循环都运行完毕。相对于使用管道来说,WaitGroup 轻巧了许多。 最后,如果要搞裂成函数,得用引用传入,指针变量: WaitGroup对象不是一个引用类型 WaitGroup对象不是一个引用类型,在通过函数传值的时候需要使用地址: #cat waitgrouppointer.go package main import ( "fmt" "sync" //"time" ) func main() { wg := sync.WaitGroup{} wg.Add(100) for i := 0; i < 100; i++ { go f(i, &wg) } wg.Wait() } // 一定要通过指针传值,不然进程会进入死锁状态 func f(i int, wg *sync.WaitGroup) { fmt.Println(i) wg.Done() } 以上来自:https://blog.csdn.net/u013474436/article/details/88749749 溯源来自:https://mp.weixin.qq.com/s/s9G6yDqfeFepbKT6DJASng #cat wg.go package main import ( "fmt" "sync" ) func main() { ok := true for i := 0; i <1000; i ++ { var arr []int wg := sync.WaitGroup{} for j := 0; j <2; j ++ { wg.Add(1) go func() { defer wg.Done() arr = append(arr, i) }() } wg.Wait() if len(arr) < 2 { fmt.Printf("error:%d \n", i) ok = false break } } if ok { fmt.Println("ok") } } 判断 key 是否在 map 中 var nameList = map[string]string{"姓名": "李四", "性别": "男"} name, ok := nameList["姓名"] // 假如 key 存在,则 ok = true,否则,ok = false if ok { fmt.Println(name) 来自:https://blog.csdn.net/weixin_38168322/article/details/99948042?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control Generated by Jackxiang's Bo-blog 2.1.1 Release