package mainimport ( "fmt" "runtime" "time")// 用通道串联goroutine流水线// 实现方式:将goroutine之间通讯所需的chan存入chs,// 创建流水线开始的goroutine,向chs[0]写入0,// 第二个goroutine从chs[0]读出数据并做加一处理,然后写入chs[1]交给流水线中下一个goroutine// ......// 统计程序消耗的内存,在超过1G时终止程序func ex9_4() { // 获得目前内存使用情况 getMemSys := func() uint64 { mem := runtime.MemStats{} runtime.ReadMemStats(&mem) return mem.Sys } before := getMemSys() chs := []chan int{} start := make(chan int) chs = append(chs, start) go func() { for { start <- 0 } }() for n := 0; ; n++ { out := chs[n] in := make(chan int) chs = append(chs, in) go func(n int, in, out chan int) { for { num := <-in out <- num + 1 } }(n, in, out) // 获得程序使用内存情况 memAlloc := getMemSys() - before if memAlloc > 1024*1024*1024 { // 消耗1G内存时终止程序 fmt.Println(n, "Goroutines") // 大概11~12万,每个goroutine消耗内存9k左右 break } }}// 通过两个无缓冲的通道实现两个goroutine通信,// 每次通信都将同通信计数加一,1s内大概通信200万次func ex9_5() { ch1 := make(chan int) ch2 := make(chan int) n := 1 defer func() { fmt.Println(n) }() go func() { ch1 <- n for { n = <-ch2 n++ ch1 <- n } }() go func() { for { n = <-ch1 n++ ch2 <- n } }() time.Sleep(time.Second)}// 无缓冲通道// 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Zfunc printNoCache() { ch1 := make(chan int) ch2 := make(chan int) end := make(chan struct{}) go func() { for i := 0; i < 26; i++ { ch1 <- i + 1 fmt.Printf("%c", <-ch2) } close(ch1) }() go func() { for i := range ch1 { fmt.Print(i) ch2 <- int('A') + i - 1 } close(end) }() <-end}// 有缓冲通道// 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Zfunc printWithCache() { ch1 := make(chan int, 1) ch2 := make(chan int, 1) done := make(chan struct{}) go func() { for i := 1; i <= 26; i++ { ch2 <- i fmt.Printf("%c", <-ch1) } close(ch2) }() go func() { for n := range ch2 { fmt.Print(n) ch1 <- int('A') + n - 1 } close(ch1) close(done) }() <-done}func main() { ex9_4() ex9_5()
printNoCache() printWithCache() }
执行效果:
117415 Goroutines25081931A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z成功: 进程退出代码 0.