1.基本知识
通道类型的值本身就是并发安全的,go语言自带的唯一一个可以满足并发安全的类型。通道相当于一个先进先出的队列,发送和接收使用操作符 <-
2.初始化
make(chan type,int)
type: int, string....
int: 可选。通道的容量。0表示不带缓冲的通道,1表示带缓冲的通道。
1.初始化容量为3的双向通道
package main
import "fmt"
func main() {
ch1 := make(chan int, 3)
ch1 <- 2
ch1 <- 1
ch1 <- 3
elem1 := <-ch1
fmt.Printf("The first element received from channel ch1: %v\n",
elem1)
}
2.初始化只读管道
ch1:=make(chan<- int, 1)
example:
func getIntChan() <-chan int {
num := 5
ch := make(chan int, num)
for i := 0; i < num; i++ {
ch <- i
}
close(ch)
return ch
}
3.初始化只写管道
ch1:=make(<-chan int, 1)
example:
func SendInt(ch chan<- int) {
ch <- rand.Intn(1000)
}
3.注意
a.对同一个通道来说,同一时间发送和接收拾互斥的。
b.元素进入通道是复制的副本。
c.缓冲通道满了以后会阻塞通道。非缓冲通道一开始就会被阻塞,直到有配对的接收操作,才开始传输数据,将数据直接复制到缓冲通道,在复制给接收方。
d.如果通道为nil,直接发生永久堵塞。
e.确保由发送方关闭通道。如果接收方关闭通道,再次向发送方发送会引发panic。
4.遍历chan
这种方法有一定的局限性,如果intChan2 没有元素或者为nil,那么就会在这一行阻塞。
func getIntChan() <-chan int {
num := 5
ch := make(chan int, num)
for i := 0; i < num; i++ {
ch <- i
}
close(ch)
return ch
}
intChan2 := getIntChan()
for elem := range intChan2 {
fmt.Printf("The element in intChan2: %v\n", elem)
}
5.select语句
chan专用。类似于 switch,不过select中首先会对所有case求值,然后才开始选择,并不是顺序求值选择。如果case 语句阻塞,也代表求值失败,知道有条件满足为止。如果有多个case条件满足,则用伪随机算法随机选择一个分支执行。若所有分支都未被选中,则默认分支执行。
example1:
// 准备好几个通道。
intChannels := [3]chan int{
make(chan int, 1),
make(chan int, 1),
make(chan int, 1),
}
// 随机选择一个通道,并向它发送元素值。
index := rand.Intn(3)
fmt.Printf("The index: %d\n", index)
intChannels[index] <- index
// 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。
select {
case <-intChannels[0]:
fmt.Println("The first candidate case is selected.")
case <-intChannels[1]:
fmt.Println("The second candidate case is selected.")
case elem := <-intChannels[2]:
fmt.Printf("The third candidate case is selected, the element is %d.\n", elem)
default:
fmt.Println("No candidate case is selected!")
}
example2:
intChan := make(chan int, 1)
// 一秒后关闭通道。
time.AfterFunc(time.Second, func() {
close(intChan)
})
select {
case _, ok := <-intChan:
if !ok {
fmt.Println("The candidate case is closed.")
break
}
fmt.Println("The candidate case is selected.")
}
网友评论