注:自己踩的一个:如果主函数创建一个通道(chan),调用的函数把这个通道关闭,那么往这个通道写数据就会崩溃,但是读值得话,就是这个类型的默认值
如果说goroutine 是 Go 程序并发的执行体,通道就是它们之间的连接。通道是可以让一个 goroutine 发送特定值到另一个 goroutine 中的通信机制。每一个通道是一个具体类型的导管,叫做通道的元素类型。
package main
import "fmt"
func main() {
messages := make(chan string)
go func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
1.1 无缓冲通道(同步通道)
无缓冲通道上的发送操作将会阻塞,直到另一个 goroutine 在相应的通道上执行接收操作,这是值传送完成,两个 goroutine 都可以继续执行。相反,如果接受操作先执行,接收方奖杯阻塞,直到另一个goroutine 发送数据到通道。
使用无缓冲通道进行通信就会导致 发送和接收的goroutine 同步化。因此,无缓冲的通道也被称为同步通道
1.2 管道
通道可以用来连接 goroutine ,这样一个的输出就是另一个的输入。这就叫 管道(pipe)。
1.3 缓冲通道
缓冲通道有一个元素队列,队列的最大长度在创建的时候通过 make 的容量参数来设置。
ch := make(chan int 3) //创建了可以容纳三个int的缓冲通道
ch <- 1
ch <- 2
ch <- 3
//这时,通道已满,那么第四个发送语句就会被阻塞
1.4 单向通道类型
out chan<- int // 只能发送通道
in <-chan int // 只能接受通道
在任何赋值操作中,都可以将双向通道转换为单向通道,但是反过来不行。
func counter(out chan<- int){
for x := 0; x <100; x++{
out<- x
}
close(out)
}
func squarer(out chan<- int, in <-chan int){
for v := range in{
out<- v*v
}
close(out)
}
func print(in <-chan int){ //这里的参数把 双向通道转换为 单向通道
for v := range in{
fmt.Println(v)
}
}
func main(){
c1 := make(chan int)
c2 := make(chan int)
go counter(c1)
go squarer(c2,c1)
print(c2)
}