package main import ( "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) } // 無緩衝通道 // 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z func 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 } // 有緩衝通道 // 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z func 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()
}
執行效果:app
117415 Goroutines 2508193 1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z 1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z 成功: 進程退出代碼 0.