go语言-channel

笔记 / 2021-03-15

作用

goroutine之间互相通信

无缓冲channel

  • make(chan xxx)
  • 无缓冲的channel会阻塞,必须等待从channel取出才结束
package main

import "fmt"

func main() {

	// 无缓冲channel
	c:=make(chan int)
	go func() {
		defer fmt.Println("goroutine exit")
		fmt.Println("goroutine running ...")
		// 发送给channel
		c<-0
	}()

	// 读取channel数据
	res:=  <-c
	fmt.Println(res)

	defer fmt.Println("main goroutine exit")
}

goroutine running ...
goroutine exit
0
main goroutine exit

有缓冲channel

  • make(chan xxx,size)
  • channel满了再次添加会阻塞
  • channel空了再次取出会阻塞
package main

import (
	"fmt"
	"time"
)

func main() {
	c := make(chan int,3)
	fmt.Println("init len:",len(c),"cap:",cap(c))
	go func() {
		defer fmt.Println("child goroutine exit")
		for i:=0;i<5;i++ {
			c<-i
			fmt.Println("send:",i,"len:",len(c),"cap:",cap(c))
		}
	}()


	time.Sleep(3*time.Second)
	for i:=0;i<5;i++{
		fmt.Println(<-c)
	}

	defer fmt.Println("main goroutine exit")

}

init len: 0 cap: 3
send: 0 len: 1 cap: 3
send: 1 len: 2 cap: 3
send: 2 len: 3 cap: 3
0
1
2
3
send: 3 len: 3 cap: 3
send: 4 len: 0 cap: 3
child goroutine exit
4
main goroutine exit

关闭channel

  • close(xxx)
  • 只有不需要发送数据时才需要关闭channel
  • 关闭channel后无法再次发送数据
  • 关闭channel后可以继续接受数据
  • nil channel不可收发
package main

import "fmt"

func main() {
	c:= make(chan int)

	go func() {
		for i:=0;i<3;i++{
			c<-i
		}
		// 当不需要再次发送数据后需要关闭channel,如果被关闭可能会引发死锁
		close(c)
	}()

	for{
		// 如果 channel 没有关闭则 ok 为ture 当channel内没有数据后为false
		 if res,ok:= <-c;ok{
		 	fmt.Println(res)
		}else {
			break
		 }
	}
}

0
1
2