作用

goroutine之间互相通信

无缓冲channel

  • make(chan xxx)
  • 无缓冲的channel会阻塞,必须等待从channel取出才结束
  1. package main
  2. import "fmt"
  3. func main() {
  4. // 无缓冲channel
  5. c:=make(chan int)
  6. go func() {
  7. defer fmt.Println("goroutine exit")
  8. fmt.Println("goroutine running ...")
  9. // 发送给channel
  10. c<-0
  11. }()
  12. // 读取channel数据
  13. res:= <-c
  14. fmt.Println(res)
  15. defer fmt.Println("main goroutine exit")
  16. }
  1. goroutine running ...
  2. goroutine exit
  3. 0
  4. main goroutine exit

有缓冲channel

  • make(chan xxx,size)
  • channel满了再次添加会阻塞
  • channel空了再次取出会阻塞
  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. c := make(chan int,3)
  8. fmt.Println("init len:",len(c),"cap:",cap(c))
  9. go func() {
  10. defer fmt.Println("child goroutine exit")
  11. for i:=0;i<5;i++ {
  12. c<-i
  13. fmt.Println("send:",i,"len:",len(c),"cap:",cap(c))
  14. }
  15. }()
  16. time.Sleep(3*time.Second)
  17. for i:=0;i<5;i++{
  18. fmt.Println(<-c)
  19. }
  20. defer fmt.Println("main goroutine exit")
  21. }
  1. init len: 0 cap: 3
  2. send: 0 len: 1 cap: 3
  3. send: 1 len: 2 cap: 3
  4. send: 2 len: 3 cap: 3
  5. 0
  6. 1
  7. 2
  8. 3
  9. send: 3 len: 3 cap: 3
  10. send: 4 len: 0 cap: 3
  11. child goroutine exit
  12. 4
  13. main goroutine exit

关闭channel

  • close(xxx)
  • 只有不需要发送数据时才需要关闭channel
  • 关闭channel后无法再次发送数据
  • 关闭channel后可以继续接受数据
  • nil channel不可收发
  1. package main
  2. import "fmt"
  3. func main() {
  4. c:= make(chan int)
  5. go func() {
  6. for i:=0;i<3;i++{
  7. c<-i
  8. }
  9. // 当不需要再次发送数据后需要关闭channel,如果被关闭可能会引发死锁
  10. close(c)
  11. }()
  12. for{
  13. // 如果 channel 没有关闭则 ok 为ture 当channel内没有数据后为false
  14. if res,ok:= <-c;ok{
  15. fmt.Println(res)
  16. }else {
  17. break
  18. }
  19. }
  20. }
  1. 0
  2. 1
  3. 2