【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")
}
相关文章
|
1月前
|
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`,以及它们的基本用法和功能。
29 6
|
1月前
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
31 3
|
2月前
|
数据库连接 Go API
Golang中的25个常见错误:更好地进行go编程的综合指南
Golang中的25个常见错误:更好地进行go编程的综合指南
|
2月前
|
存储 安全 Go
Go 并发编程精粹:掌握通道(channels)的艺术
Go 并发编程精粹:掌握通道(channels)的艺术
|
2月前
|
存储 消息中间件 缓存
|
2月前
|
Go 开发者
深入理解Go语言的通道:概念与使用
【8月更文挑战第31天】
29 0
|
2月前
|
Go 开发者
|
2月前
|
Go 开发者
|
3月前
|
运维 监控 测试技术
Golang质量生态建设问题之接入并使用Go单元测试插件的问题如何解决
Golang质量生态建设问题之接入并使用Go单元测试插件的问题如何解决
|
3月前
|
自然语言处理 Go 数据处理
云计算自旋锁问题之引入Golang插件系统后iLogtail的输入输出通道和处理能力如何解决
云计算自旋锁问题之引入Golang插件系统后iLogtail的输入输出通道和处理能力如何解决
32 1
下一篇
无影云桌面