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

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别?

在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。

  1. 无缓冲的 channel

行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel 发送数据,它会阻塞,直到另一个 goroutine 从该 channel 中接收数据。反之亦然,接收方在准备好接收数据之前,发送方无法继续执行。
用法:适合在两个 goroutines 之间实现精确的同步,确保它们在同一时刻传递数据。
优点:
保证了发送和接收的同步,可以避免某些类型的并发错误。
更简单,适合需要严格按顺序处理任务的场景。
缺点:
性能上可能存在瓶颈,因为必须等待对应的发送或接收操作才能继续执行。

无缓冲的 Channel 示例

package mainimport ("fmt""time"
)func main() {// 创建一个无缓冲的 channelch := make(chan int)// 启动一个 goroutine 来接收数据go func() {// 接收数据之前会阻塞,直到 main goroutine 发送数据val := <-chfmt.Println("接收到的数据:", val)}()// 模拟一些操作time.Sleep(1 * time.Second)// 发送数据到 channel,会阻塞直到接收方读取数据ch <- 42fmt.Println("数据已发送")
}

由于是无缓冲的 channel,main goroutine 在发送 42 时会阻塞,直到 goroutine 从 channel 中接收到这个值,程序才会继续执行。
2. 有缓冲的 channel

行为:有缓冲的 channel 容许在 channel 中存储一定数量的数据元素,发送方可以在 channel 未满时继续发送数据,而无需等待接收方。接收方只有当 channel 非空时才会接收数据。
用法:适合发送方和接收方的处理速度不一致的情况,允许发送方先发送一部分数据,接收方稍后接收。
优点:
提供了一定的并发灵活性,发送方可以在接收方未准备好时先发送一定数量的数据。
提高了性能,减少了因为同步阻塞而导致的性能损耗。
缺点:
如果缓冲区设计不当,可能会出现缓冲区溢出或浪费资源的情况。
由于有缓冲的存在,可能会导致发送和接收之间的时间不同步,增加调试和排查问题的难度。
总结
无缓冲的 channel 强调的是同步性,适合需要严格同步的场景。

有缓冲的 channel 提供更多的灵活性,允许在并发处理中有更大的自由度,不需要完全同步。
在使用中,可以根据具体场景选择合适的 channel 类型。例如,在生产者-消费者模型中,有缓冲的 channel 可以防止生产者等待消费者处理;而在需要精确同步的任务中,无缓冲 channel 则更加合适。

有缓冲的 Channel 示例

package mainimport ("fmt""time"
)func main() {// 创建一个带有缓冲区大小为 2 的 channelch := make(chan int, 2)// 发送两个数据到 channelch <- 1fmt.Println("发送了数据 1")ch <- 2fmt.Println("发送了数据 2")// 此时,由于缓冲区还有空间,发送不会阻塞go func() {// 延迟读取,模拟一些操作time.Sleep(2 * time.Second)val := <-chfmt.Println("接收到的数据:", val)}()// 继续发送数据time.Sleep(1 * time.Second)ch <- 3fmt.Println("发送了数据 3")// 接收数据time.Sleep(2 * time.Second)val := <-chfmt.Println("接收到的数据:", val)
}

这里的 channel 有缓冲区大小为 2,因此前两个 ch <- 操作不会阻塞,因为缓冲区有足够空间。第三次发送数据时,如果缓冲区已满,发送方会阻塞,直到接收方读取数据并释放空间。


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

相关文章:

  • 经典文献阅读之--iDet3D(交互式3D目标检测器)
  • GitHub 上 fork 的代码,如何保持与原作者同步更新
  • 一篇文章告诉你小程序为什么最近这么火?
  • 【C++】容器
  • 基于51单片机的倒计时定时器proteus仿真
  • 手机玩机常识-------诺基亚系列机型3/5/6/7/8详细的刷机教程步骤 手机参考救砖刷机教程
  • 用EA和SysML一步步建模(05)使命声明-解构需求01
  • C++实现俄罗斯方块(Windows控制台版)
  • 21. 合并两个有序链表【 力扣(LeetCode) 】
  • 项目实战系列三: 家居购项目 第四部分
  • LabVIEW程序员是怎样成长为大佬
  • 跨系统环境下LabVIEW程序稳定运行
  • 农场管理系统小程序的设计
  • 包机制,javadoc生成文档,用户交互scanner
  • 发现 Unstructured 的 “TensorrtExecutionProvider“ 比 “CUDAExecutionProvider“ 慢
  • flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志
  • 【2.1 深度学习中的感知机是什么】
  • AI模型:到底是追求全能还是要追求专精?这是一个问题
  • Exchange 服务器地址列表的配置方法与注意事项
  • 唯徳知识产权产权系统存在任意文件读取漏洞