go之通道类型

作者: 东京的雨不会淋湿首尔 | 来源:发表于2019-06-12 19:41 被阅读1次

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.")
}

相关文章

  • go之通道类型

    1.基本知识 通道类型的值本身就是并发安全的,go语言自带的唯一一个可以满足并发安全的类型。通道相当于一个先进先出...

  • 通道

    通道是 Go 并发编程中重要的一员 基础知识 通道是 Go 自带的,唯一一个可以满足并发安全性的类型。 声明并初始...

  • <>

    通道的基本操作# 通道本身是并发安全的,这也是go语言自带的唯一一个可以满足并发安全的的类型。 通道的初始化 通道...

  • Golang通道Channel详解

    通道类型是Go自带的,相当于是一个先进先出的队列,同时唯一一个可以满足并发安全性的类型。声明一个通道类型变量的时候...

  • Go核心语言编程 - 复合数据类型(3)

    Go对应的复合数据类型有数组,字典,指针,切片,通道,结构和结构,他们字面类型如下: • 指针 • 数组• 数组初...

  • golang实战笔记

    golang实战笔记 一、集合类型 1.值指针和引用类型a、go语言变量持有相应的值,列外:通道、函数、方法、映射...

  • Go类型转换(一)

    除常量、别名类型以及未命名类型外,Go强制要求使用显式类型转换。 1.语法歧义如果转换的目标是指针、单向通道或没有...

  • Go语言 参数传递究竟是值传递还是引用传递的问题分析

    之前我们谈过,在Go语言中的引用类型有:映射(map),数组切片(slice),通道(channel),方法与函数...

  • Go语言第3天 - 常用数据类型

    以下内容部分参考自Go语言基础数据类型Go语言中的数组切片:特立独行的可变数组Go语言数据类型-数组Go标准容器之...

  • Go语言标准库之JSON编解码

    Go语言标准库之JSON编解码 基本的类型 Go语言中的数据类型和JSON的数据类型的关系 bool -> JSO...

网友评论

    本文标题:go之通道类型

    本文链接:https://www.haomeiwen.com/subject/ytllfctx.html