funcmain() { // 是go一种特殊的数据类型,有点像Linux系统中的管道/消息队列 c := make(chanbool) gofunc() { fmt.Println("Go Go Go!") c <- true }() // 等待从通道里读取值 <-c }
1 2 3 4 5 6 7 8 9 10 11 12
funcmain() { c := make(chanbool) gofunc() { fmt.Println("Go Go Go!") c <- true close(c) }() // 可以使用for range来迭代不断操作channel,直到关闭channel for v := range c { fmt.Println(v) } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funcmain() { // 有缓存的 channel,主 goroutine 发送后可能直接退出,因此不保证输出。 c := make(chanbool, 1) gofunc() { fmt.Println("Go Go Go!") <-c }() c <- true }
funcmain() { // 无缓存的 channel 会在发送/接收两端同步,输出:Go Go Go! c := make(chanbool) gofunc() { fmt.Println("Go Go Go!") <-c }() c <- true }
// 解决上面不能判断所有 goroutine 是否执行完的问题: // 通过创建带缓冲区的 channel 收集完成信号。 funcmain() { runtime.GOMAXPROCS(runtime.NumCPU()) c := make(chanbool, 10) for i := 0; i < 10; i++ { go Go(c, i) } for i := 0; i < 10; i++ { <-c } }
funcGo(c chanbool, index int) { a := 1 for i := 0; i < 100000000; i++ { a += i } fmt.Println(index, a)
func Pingpong() { i := 0 for { fmt.Println(<-c) c <- fmt.Sprintf("From Pingpong: Hi, #%d", i) i++ } }
func main() { c = make(chan string) go Pingpong() for i := 0; i < 10; i++ { c <- fmt.Sprintf("From main: Hello, #%d", i) fmt.Println(<-c) } }
输出: From main: Hello, #0 From Pingpong: Hi, #0 From main: Hello, #1 From Pingpong: Hi, #1 From main: Hello, #2 From Pingpong: Hi, #2 From main: Hello, #3 From Pingpong: Hi, #3 From main: Hello, #4 From Pingpong: Hi, #4 From main: Hello, #5 From Pingpong: Hi, #5 From main: Hello, #6 From Pingpong: Hi, #6 From main: Hello, #7 From Pingpong: Hi, #7 From main: Hello, #8 From Pingpong: Hi, #8 From main: Hello, #9 From Pingpong: Hi, #9