Go根本学习08-并发安全型范例-通道(chan)深入研究

[复制链接]
发表于 2026-1-14 06:53:39 | 显示全部楼层 |阅读模式
在前面学习中相识到对于单值变量,如:int、string;多值变量,如:map存在多协程对资源竞争的并发题目,为相识决并发性通常须要引入sync.Mutex办理。 通道范例本身就是并发安全的,是Go语言自带的、唯逐一个可以满意并发安全性的范例。
chan根本利用和明白

  1. package main
  2. import (
  3.         "fmt"
  4. )
  5. func main() {
  6.    
  7.    
  8.         // 使用make声明并初始化一个int型的带缓冲的通道,并将其容量设置为3
  9.         ch1 := make(chan int, 3)
  10.         // 使用make声明并初始化一个int型的不带缓冲的通道,其容量为0
  11.         ch2 := make(chan int)
  12.         // 声明一个int型的通道
  13.         var ch3 chan int
  14.         // 使用接送操作符 <- 向通道ch1中发送int型数据1
  15.         go func(){
  16.    
  17.    
  18.                 ch1 <- 1
  19.                 ch1 <- 2
  20.                 ch1 <- 3
  21.         }()
  22.         // 使用接送操作符 <- 从通道ch1中读取数据,下面的短变量表达式左边有两个变量num, ok:其中ok用于判断通道ch1是否关闭,
  23.         // 当ok == ture时表示通道没有关闭,可以读取数据并将其保存到变量nums中,当ok == false时表示通道关闭,不能读取数据。
  24.         // 此外读取通道中的数据,可以直接使用num := <- ch1进行读取,不添加第二个判断通道是否关闭的条件,此时有风险存在
  25.         num, ok := <-ch1
  26.         if ok {
  27.    
  28.    
  29.                 fmt.Println(num)
  30.         }
  31.         close(ch1)
  32.         close(ch2)
  33.         // close(ch3)
  34. }
复制代码
  对于通道的根本声明方式有三种:声明并初始化带缓冲的通道(ch1);声明并初始化一个不带缓冲的通道(ch2);仅仅声明一个通道(ch3)
什么是通道:一个通道相称于一个先辈先出(FIFO)的队列。也就是说,通道中的各个元素值都是严格地按照发送的序次分列的,先被发送通道的元素值肯定会先被吸收。元素值的发送和吸收都须要用到利用符<-。我们也可以叫它接送利用符。一个左尖括号紧接着一个减号形象地代表了元素值的传输方向。
  上述代码对于通道3由于仅仅声明没有举行初始化,以是不能实行关闭利用。 对于未初始化的通道实行close利用报panic:
  1. panic: close of nil channel
  2. // go语言中通道类型为引用类型,故只声明而未初始化时通道值为nil。
复制代码
通道模子:单通道、双通道

双向通道

channel两头的goroutine既可以发送数据也可以继承数据。

默认环境下利用创建的通道即为双向通道。
单向通道

创建的channel规定了数据流向,对于channel双端,分别一端作为发送者(producer)、一端作为吸收者(consumer),只能发送大概吸收。

创建单向通道:对于单向通道而言,发送和吸收均是站在数据的角度:

      
  • 假如向通道中发送数据,则为发送通道。  
  • 假如从通道中吸收数据,则为吸收通道。
  1. // 单向发送通道
  2. ch1 := make(chan<-, 2)
  3. var ch2 chan<-
  4. // 单向接收通道
  5. ch3 := make(<-chan, 2)
  6. var ch4 <-chan
复制代码
单向通道的作用


      
  • 单向通道的重要束缚其他代码的运动。 看下面示例代码:
  1. package main
  2. import "fmt"
  3. /*
  4. *
  5. 创建单向通道
  6. */
  7. func main() {
  8.    
  9.    
  10.         // 定义带缓冲通道
  11.         ch := make(chan int, 3)
  12.         producer(ch, 7)
  13.         ans := consumer(ch)
  14.         fmt.
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表