当前位置: 首页 > news >正文

深入理解 Go 语言并发编程--管道(channel) 的底层原理

        管道是 Go 语言协程间通信的一种常用手段,管道的读写操作也有可能会阻塞用户协程,也就是说有可能会切换到调度器。协程因为管道而阻塞时,只有当其他协程再次读或者写管道时,才有可能解除这个协程的阻塞状态。

1. 管道的基本用法

        管道是 Go 语言协程间通信的一种常用手段,可以分为无缓冲管道和有缓冲管道。因为无缓冲管道本身没有容量,不能缓存数据,所以只有当协程在等待读时,写操作才不会阻塞协程;或者当有协程在等待写时,读操作才不会阻塞协程。因为有缓冲管道本身有一定容量,可以缓存一定数据,所以当协跑第一执行写操作时,即使没有其他协程在等待读,只要管道还有剩余容量,写操作就不会阻塞协程;或者当协程执行读操作时,即使没有其他协程在等待写,只要管道还有剩余数据,读操作就不会阻塞协程。

        下面写一个简单的 Go 程序,学习管道的基本用法,代码如下所示:

package mainimport ("fmt""time"
)func main() {queue := make(chan int, 1)go func() {for {data := <-queue     //读取fmt.Print(data, "") //0 1 2 3 4 5 6 7 8 9}}()for i := 0; i < 10; i++ {queue <- i //写入}time.Sleep(time.Second)
}

        参考上面代码,主协程循环向管道写入整数,子协程循环从管道读取数据。主协程休眠 1s 是为了防止主协程结束,整个 Go 程序退出,导致子协程也提前结束。函数 make 用于初始化 Go 语言的一些内置类型,如切片 slice、散列列 map 以及管道 chan。注意用函数 make 初始化时,第一个参数 chan int 表示管道只能用来传递整型数据,第二个参数表示管道的容量是 1,即最多只能缓存一个整型数据。

        管道的操作还是比较简单的,无非就是读、写以及关闭操作。这里提出一个问题,如果程序没有初始化管道,却执行读或者写操作会发生什么呢?或者说,如果一个管道已经被关闭了,这时候执行读或者写操作会发生什么呢?我们写一些简单的 Go 程序测试一下。

        第 1 个程序:不初始化管道,直接


http://www.mrgr.cn/news/14419.html

相关文章:

  • 2024.8.29 作业
  • 【准则化的思想】绝对充分度
  • 探索 Linux 内核启动过程
  • 爬取数据时,如何避免违法问题
  • 使用ddns-go实现自动配置IPv6的DDNS
  • 数据库(专业存储数据)
  • 【工具使用】clang++踩坑记录
  • mac系统下Java环境安装
  • React滚动加载(无限滚动)功能实现
  • 「个性化定制」引领美业新潮流|博弈美业SaaS系统探索未来美业的个性化革新
  • 恒电流间歇滴定法 (GITT) 测试教程
  • 高级MySQL数据库备份脚本
  • Flask-RESTFul 之 RESTFul 的响应处理
  • 离线环境玩转 Tauri
  • WPF- vs中的WPF应用项目模板 如何自己实现
  • 【前端面试基础】计算机网络、浏览器、操作系统
  • 大数据基础:离线与实时数仓区别和建设思路
  • AI模型:全能与专精的较量与未来潜力探讨
  • Vue vue/cli3 与 vue/cli4 v-for 和 v-if 一起使用冲突
  • IPv4地址和子网掩码