【go系列5】golang中的通道

简介: 【go系列5】golang中的通道

golang中的通道类型是一种特殊的类型, 类型名字为chan。在任何时候,同时只有一个goroutine访问通道进行并发和获取数据,goroutine间通过通道就可以进行通信。我们可以通过go关键字创建goroutine。

通道本身是同步的,通道的发送和接受数据默认是同步的,且遵循先进先出的规则以保证数据发送的顺序。


通道分为双向通道和单向通道。

双向通道:

chan1 := make(chan int, 10)

单向通道

#单向只写通道,10 表示通道的容量
chan2 := make(chan <- int, 10)
#单向只读通道,10表示通道的容量
chan3 := make(<- chan int, 10)
package main
import (
  "time"
  "github.com/golang/glog"
)
func read(readChan <-chan int) {
  for data := range readChan {
    glog.Info(data)
  }
}
func write(writeChan chan<- int) {
  for i := 0; i < 100; i++ {
    writeChan <- i
    glog.Infof("write: %s", i)
  }
}
func main() {
  // 双向通道
  writeReadChan := make(chan int)
  // 传入双向通道自动会转换成一个单项通道
  go write(writeReadChan)
  glog.Info("start to read data from channel!")
  // 传入双向通道会自动转换成一个单项通道`
  go read(writeReadChan)
  // 关闭chan
  close(writeReadChan)
  time.Sleep(time.Second * 100)
  glog.Info("finishedAll!!")
}
  1. 通道分无缓冲通道和缓冲通道
  • 无缓冲通道
unbufferChan1 := make(chan int)
unbufferChan2 := make(chan int, 0)
  • 缓冲通道
bufferChan := make(chan int, 1)

无缓冲通道的特点是,发送的数据需要被读取后,发送才会完成,它阻塞场景:

  1. 通道中无数据,但执行读通道。
  2. 通道中无数据,向通道写数据,但无协程读取。
func occasion1() {
    noBufChan := make(chan int)
    <-noBufChan
    fmt.Println("read ")
}
// 场景2
func occasion2() {
    ch := make(chan int)
    ch <- 1
    fmt.Println("write success no block")
}

有缓存通道的特点是,有缓存时可以向通道中写入数据后直接返回,缓存中有数据时可以从通道中读到数据直接返回,这时有缓存通道是不会阻塞的,它阻塞场景是:

  1. 通道的缓存无数据,但执行读通道。
  2. 通道的缓存已经占满,向通道写数据,但无协程读。
// 场景1
func occasion1() {
    bufCh := make(chan int, 2)
    <-bufCh
    fmt.Println("read from no buffer channel success")
}
// 场景2
func occasion2() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
  ch <- 3
    fmt.Println("write success no block")
}
相关文章
|
22天前
|
存储 Go 开发者
Go语言中的并发编程与通道(Channel)的深度探索
本文旨在深入探讨Go语言中并发编程的核心概念和实践,特别是通道(Channel)的使用。通过分析Goroutines和Channels的基本工作原理,我们将了解如何在Go语言中高效地实现并行任务处理。本文不仅介绍了基础语法和用法,还深入讨论了高级特性如缓冲通道、选择性接收以及超时控制等,旨在为读者提供一个全面的并发编程视角。
|
22天前
|
JSON Go 开发者
go-carbon v2.5.0 发布,轻量级、语义化、对开发者友好的 golang 时间处理库
carbon 是一个轻量级、语义化、对开发者友好的 Golang 时间处理库,提供了对时间穿越、时间差值、时间极值、时间判断、星座、星座、农历、儒略日 / 简化儒略日、波斯历 / 伊朗历的支持。
36 4
|
22天前
|
安全 Java Go
Go语言中的并发编程:掌握goroutine与通道的艺术####
本文深入探讨了Go语言中的核心特性——并发编程,通过实例解析goroutine和通道的高效使用技巧,旨在帮助开发者提升多线程程序的性能与可靠性。 ####
|
1月前
|
存储 Cloud Native Shell
go库介绍:Golang中的Viper库
Viper 是 Golang 中的一个强大配置管理库,支持环境变量、命令行参数、远程配置等多种配置来源。本文详细介绍了 Viper 的核心特点、应用场景及使用方法,并通过示例展示了其强大功能。无论是简单的 CLI 工具还是复杂的分布式系统,Viper 都能提供优雅的配置管理方案。
|
1月前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
2月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
3月前
|
Go
golang语言之go常用命令
这篇文章列出了常用的Go语言命令,如`go run`、`go install`、`go build`、`go help`、`go get`、`go mod`、`go test`、`go tool`、`go vet`、`go fmt`、`go doc`、`go version`和`go env`,以及它们的基本用法和功能。
73 6
|
3月前
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
67 3
|
4月前
|
数据库连接 Go API
Golang中的25个常见错误:更好地进行go编程的综合指南
Golang中的25个常见错误:更好地进行go编程的综合指南
|
4月前
|
存储 安全 Go
Go 并发编程精粹:掌握通道(channels)的艺术
Go 并发编程精粹:掌握通道(channels)的艺术