1、无缓冲通道

Go语言中无缓冲的通道(unbuffered channel)是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。

 

2、带缓冲的通道

Go语言中有缓冲的通道(buffered channel)是一种在被接收前能存储一个或者多个值的通道。这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。通道会阻塞发送和接收动作的条件也会不同。只有在通道中没有要接收的值时,接收动作才会阻塞。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。

有缓冲的通道和无缓冲的通道之间的一个很大的不同:无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换;有缓冲的通道没有这种保证。

在无缓冲通道的基础上,为通道增加一个有限大小的存储空间形成带缓冲通道。带缓冲通道在发送时无需等待接收方接收即可完成发送过程,并且不会发生阻塞,只有当存储空间满时才会发生阻塞。同理,如果缓冲通道中有数据,接收时将不会发生阻塞,直到通道中没有数据可读时,通道将会再度阻塞。

1)创建带缓冲的通道

通道实例 := make(chan 通道类型, 缓冲大小)

  • 通道类型:和无缓冲通道用法一致,影响通道发送和接收的数据类型。
  • 缓冲大小:决定通道最多可以保存的元素数量。
  • 通道实例:被创建出的通道实例。

 

3、通道的多路复用

Go语言中提供了 select 关键字,可以同时响应多个通道的操作。由 select 开始一个新的选择块,每个选择条件由 case 语句来描述,每个 case 语句都必须是一个面向 channel 的操作,大致结构如下:

select{
    case 操作1:
        响应操作1
    case 操作2:
        响应操作2
    …
    default:
        没有操作情况
}

  • 操作1、操作2:包含通道收发语句。
  • 响应操作1、响应操作2:当操作发生时,会执行对应 case 的响应操作。
  • default:当没有任何操作时,默认执行 default 中的语句。

 

4、关闭通道

使用 close() 来关闭一个通道:close(ch)

关闭的通道依然可以被访问,访问被关闭的通道将会发生一些问题。

被关闭的通道不会被置为 nil。如果尝试对已经关闭的通道进行发送,将会触发宕机。

从已经关闭的通道接收数据或者正在接收数据时,将会接收到通道类型的零值,然后停止阻塞并返回。

示例:

package main

import "fmt"

func main() {
	ch := make(chan int, 2)
	ch<-0
	close(ch)
	for  i := 0; i < 2 ; i++  {
		v, ok := <-ch
		fmt.Println(v, ok)
	}
}

  

 

 

posted on 2019-12-08 19:43  acgame  阅读(337)  评论(0编辑  收藏  举报