golang , chan学习
管道是阻塞的,管道的写法,管道内容读取,和写入
package main
import "fmt"
func main() {
// 管道声明 chan是关键字 int是类型
// var chan1 chan int
chan1 := make(chan int)
fmt.Println(chan1)
// 无缓冲通道,不会存储数据,会直接流入管道
// 它的容量是 0,不能存储任何数据
// 数据并不会在 channel 中做任何停留。这也意味着,无缓冲 channel 的发送和接收操作是同时进行的,它也可以称为同步 channel
c := make(chan int)
go func() {
defer fmt.Println("goroutine over")
fmt.Println("goroutine正在运行...")
c <- 666 // 流入管道
}()
// 管道的读取是会被阻塞的
// 接收:receive
num, ok := <-c
if ok {
println("the chan is ok and num is ", num)
}
fmt.Println("main goroutine over")
}
带容量的chain,如果满了,那么发送的时候会阻塞,如果空了,那么接受的时候会阻塞
package chandemo
import (
"fmt"
"time"
)
func bufferChannel() {
// 带容量的chan
c := make(chan int, 3)
// len是实际的,cap是客观的容量
fmt.Println("len(c) = , cap(c) = ", len(c), cap(c))
go func() {
defer fmt.Println("子go结束")
// 轮询向管道发送数据
// 如果队列已满,则阻塞等待,直到另一个 goroutine 执行,接收操作释放队列的空间
for i := 0; i < 3; i++ {
c <- i
fmt.Println("子go程正在运行,发送的元素=i", i, " len(C) = ", len(c), "cap(c)", cap(c))
}
}()
// 保证先发送完成
time.Sleep(2 * time.Second)
// 循环接收数据
// 接收操作是从队列的头部获取元素并把它从队列中删除,如果队列为空,则阻塞等待,直到另一个 goroutine 执行,发送操作插入新的元素
for i := 0; i < 3; i++ {
num := <-c
fmt.Println("num of i is ", num)
}
fmt.Println("main 结束")
}