01、使用chan控制程序结束
package main import "fmt" func main() { c := make(chan bool) go func() { fmt.Println("hello") c <- true }() <-c }
02、遍历chan
1 package main 2 3 import "fmt" 4 5 func main() { 6 c := make(chan bool) 7 go func() { 8 fmt.Println("hello") 9 c <- true 10 close(c)//不手动关闭chan,会导致for循环无法结束,go所有协程都在等待导致死锁,从而崩溃 11 }() 12 for v :=range c { 13 fmt.Println("chan的值", v) 14 } 15 }
03、chan无缓存时,是同步的,写了,需要被读。若有缓存,则写了,不一定需要被读
1 package main 2 3 import "fmt" 4 5 func main() { 6 c := make(chan bool, 1)//指定了大小,有缓存 7 go func() { 8 fmt.Println("hello") 9 <-c 10 }() 11 c <- true//因为有缓存,读不到,则直接结束 12 }
04、控制10个协程执行完成后程序退出
1 package main 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 func main() { 9 now := time.Now() 10 defer fmt.Println("耗时不用函数", time.Now().Sub(now).Seconds())//耗时0 11 defer func() { 12 fmt.Println("耗时用函数", time.Now().Sub(now).Seconds())//耗时正常 13 }() 14 15 c := make(chan bool, 10) 16 for i := 0; i < 10; i ++ { 17 go hello(c, i) 18 } 19 for i := 0; i < 10; i++ { 20 <-c 21 } 22 } 23 24 func hello(c chan bool, index int) { 25 fmt.Println("hello, ", index) 26 c <- true 27 }
05、使用select读取多个通道
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 c1, c2 := make(chan int), make(chan string) 9 go func() { 10 for { 11 select { 12 case v1, ok := <-c1://关闭后,每次ok都为false。多个case时,随机执行一个 13 if ok { 14 fmt.Println("C1的值为:", v1) 15 } 16 case v2, ok := <-c2: 17 if ok { 18 fmt.Println("c2的值为:", v2) 19 } 20 } 21 } 22 }() 23 c1 <- 1 24 c2 <- "abc" 25 close(c1) 26 close(c2) 27 }
06、空的select会阻塞协程
1 package main 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 func main() { 9 for { 10 fmt.Println("当前时间:", time.Now()) 11 } 12 select {} 13 }
07、select超时退出
1 package main 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 func main() { 9 c := make(chan bool) 10 select { 11 case <-c: 12 case <-time.After(3*time.Second): 13 fmt.Println("超时退出") 14 } 15 }