go语言channel学习与总结(一)channel的一些基本用法

go语言中,说到并发先想到的就是goroutine,在go程序中,我们可以执行成千上万个goroutine协程,但是只是单纯的并发执行某个函数意义是不大的,既能够实现在函数与函数之间交换数据,又能使成千上万的函数一起执行,这才是go语言设计的精妙之处。

Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。

这句话就是channel的核心设计理念。

channel在Go 语言中是一种特殊的类型(引用类型)。channel像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。

下面介绍一下channel的用法:

1、创建和声明:

//声明
var ch1 chan int   // 声明一个传递整型的通道
var ch2 chan string// 声明一个传递字符串的通道
var ch3 chan []int // 声明一个传递int切片的通道
var ch4 chan map[int]int // 声明一个传递map的通道

// 下面一般用于控制通道的权限才用
// 大多用于函数的入参来作为声明
var ch1 <-chan int   // 声明一个只读整型的通道
var ch1 chan<- int   // 声明一个只写整型的通道


//创建

ch5 := make(chan int)
ch6 := make(chan int,10) // 10为channel的容量大小,当channel里面有10个元素时候,这时往里面塞会阻塞
ch7 := make(chan string)
ch8 := make(chan []int)
ch9 := make(chan map[int]int )

2、channel的一些基本操作:发送(send)、接收(receive)和关闭(close)三种操作

// 发送和接收都使用 <- 符号。

// 初始化channel
ch := make(chan int)

// 把1发送到ch中
ch <- 1 

// 从ch中接收值并赋值给变量x
x := <- ch 

// 从ch中接收值,忽略结果
<-ch       

// 关闭channel
close(ch)

以下列一下channel中的操作可能的状态:

channel可进行3种操作的情况
操作 nil的channel 正常channel 已关闭channel
<- ch 阻塞 成功或阻塞 读到零值
ch <- 阻塞 成功或阻塞 panic
close(ch) panic 成功 panic

对于nil通道的情况,也并非完全遵循上表,有1个特殊场景:当nil的通道在select的某个case中时,这个case会阻塞,但不会造成死锁。

以下关于close的一些测试用例:

// channel 练习
func main() {
	testChannelClose()
}

func testChannelClose()  {
	ch := make(chan int, 5)
	ch <- 18
	close(ch)
	x, ok := <-ch
	if ok {
		fmt.Println("received: ", x)
	}
	x, ok = <-ch
	if !ok {
		fmt.Println("channel closed, data invalid.")
	} else {
		fmt.Println("received: ", x)
	}
}

输出:
received:  18
channel closed, data invalid.

原因:channel关闭之后,原来在通道中的数据还会在缓冲区中,我们仍然还可以读出里面的数据,但是当前通道只有一个数据。所以第二次读的时候失败了。

// channel 练习
func main() {
	testChannel()
}

func testChannel() {
	ch := make(chan int, 5)
	ch <- 18
	ch <- 19
	close(ch)
	x, ok := <-ch
	if ok {
		fmt.Println("received: ", x)
	}
	x, ok = <-ch
	if !ok {
		fmt.Println("channel closed, data invalid.")
	} else {
		fmt.Println("received: ", x)
	}
}

输出:
received:  18
received:  19

原因:channel关闭之后,原来在通道中的数据还有两个数据,这时我们还可以把这俩读出来。

如上,简单阐述了channel的一些基本用法,明天我们在列一些我们channel在实际中经常用到的一些场景

猜你喜欢

转载自blog.csdn.net/shalaoq/article/details/107623569