一、channel类型 即管道,FIFO模型,分为双向,可读,可写类型。
channle通常用于go的并发执行(协程),协程之间传递数据!
1.1 创建的方法 channel必须要先创建,才能使用,一般使用make来创建!
创建的方法:
var c1 chan [value type]
c1 = make([channel type] [value type], [capacity])
说明:1)[value type] 定义的是 Channel 中所传输数据的类型。
2)[channel type] 定义的是 Channel 的类型,分为三种:可读可写,如chan int;仅可写,如chan<- int;仅可读<-chan int
3)[capacity] 是一个可选参数,其定义的是 channel 中的缓存区
实例:
var c1 chan string
c1 = make(chan string, 100)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()
fmt.Println("received: '", <- c1,"' from c1")
1.2 channel 的阻塞和非阻塞
1)如果没有设置容量,或者容量设置为0, 说明Channel没有缓存,只有sender和receiver都准备好了后它们的通讯(communication)才会发生
2)如果设置了缓存,就有可能不发生阻塞, 只有buffer满了后 send才会阻塞, 而只有缓存空了后receive才会阻塞
1.3 send操作符、receive操作符、select语句、timeout语句
1)send操作符,即ch<-,用来往Channel ch中发送数据
(1)若无缓存,channel只有在receiver准备好后send才被执行;
若有缓存,并且缓存未满,则send会被执行
(2)往一个已经被close的channel中继续发送数据会导致run-time panic
(3)往nil channel中发送数据会一致被阻塞着
实例:
ch := make(chan int)
ch<- 3+4
2)receive操作符,即<-ch,用来从channel ch中接收数据
(1)从一个nil channel中接收数据会一直被阻塞
(2)从一个被close的channel中接收数据不会被阻塞,而是立即返回,接收完已发送的数据后会返回元素类型的零值
(3)一般通过 var x, ok = <-ch 第个参数false表示关闭。(解决2中一直返回零值问题)
实例:
var x int
var ok bool
x, ok = <-ch //x 7 ; ok true
x, ok = <-ch //x 0; ok false
3)select语句,选择一组可能的send操作和receive操作去处理,用来处理通讯操作。
实例:
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
main函数中:
go func() {
fmt.Println(<-c) ///输出第一个斐波那契数列值
quit <- 0 //结束程序
}
fibonacci(c, quit)
4)timeout语句, 如果没有case需要处理,select语句就会一直阻塞着
例子我们会在2秒后往channel c1中发送一个数据,但是select设置为1秒超时,因此我们会打印出timeout 1,而不是result 1
代码实例:
c1 := make(chan string, 1)
go func() {
time.Sleep(time.Second * 2)
c1 <- "result 1"
}()
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout 1")
}
参考网址:https://www.runoob.com/w3cnote/go-channel-intro.html
其他知识点: https://www.cnblogs.com/tobycnblogs/p/9935465.html