B848e78f14c0ce3fa3826f924514b5da
go的特性-通道channel

Don’t communicate by sharing memory; share memory by communicating. (不要通过共享内存来通信,而应该通过通信来共享内存。)
这体现了 Go 语言最重要的编程理念,我们可以利用通道在多个 goroutine 之间传递数据。通道类型的值本身就是并发安全,以满足并发安全性 。

channel的定义
var ch chan int
ch = make(chan int, 10)
或者
ch1 := make(chan int, 3) 
或者
var stuChan chan interface{}
stuChan = make(chan interface{}, 10)

make后面数字,当为0时,我们可以称通道为非缓冲通道,也就是不带缓冲的通道。而当大于0,我们可以称为缓冲通道,也就是带有缓冲的通道。
区别:
从无缓存的 channel 中读取消息会阻塞,直到有 goroutine 向该 channel 中发送消息;同理,向无缓存的 channel 中发送消息也会阻塞,直到有 goroutine 从 channel 中读取消息。

有缓存的 channel 类似一个阻塞队列(采用环形数组实现)。当缓存未满时,向 channel 中发送消息时不会阻塞,当缓存满时,发送操作将被阻塞,直到有其他 goroutine 从中读取消息;相应的,当 channel 中消息不为空时,读取消息不会出现阻塞,当 channel 为空时,读取操作会造成阻塞,直到有 goroutine 向 channel 中写入消息。

一个通道相当于一个先进先出(FIFO)的队列。通道中的各个元素值都是按照发送的顺序排列的,先被发送通道的元素值一定会先被接收。元素值的发送和接收都需要用到操作符<-。我们可以叫它接送操作符。一个左尖括号紧接着一个减号。channel名字在左侧表示写入,channel名字在右侧读取。

channel的读写
package main
import (
    "fmt"
    "time"
)
func write(ch chan int) {
    for i := 0; i < 10; i++ {
        ch <- i
        fmt.Println("put data:", i)
    }
}
func read(ch chan int) {
    for {
        var b int
        b = <-ch
        fmt.Println(b)
        time.Sleep(time.Second)
    }
}
func main() {
    intChan := make(chan int, 10)
    go write(intChan)
    go read(intChan)
    time.Sleep(10 * time.Second)
}

write read 用go关键字被跑出去执行去了,所以不阻塞主进程,如果不加time.Sleep,程序可能很快退出。

channel的select控制时间超时

```
package main
import "fmt"
import "time"
func main() {
var ch chan int
ch = make(chan int, 1)
ticker := time.NewTicker(time.Second * 5)
go func() {
var i int
time.Sleep(6 * time.Second)
ch <- i
}()
select {

top Created with Sketch.