前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang channel

golang channel

作者头像
王小明_HIT
发布2023-09-22 17:35:37
1490
发布2023-09-22 17:35:37
举报
文章被收录于专栏:程序员奇点程序员奇点

golang channel

channelGolang在语言层面提供的goroutine间的通信方式,比Unix管道更易用也更轻便。channel主要用于进程内各goroutine间通信,如果需要跨进程通信,建议使用分布式系统的方法来解决。

如果说 goroutine 是 Go语言程序的并发体的话,那么 channels 就是它们之间的通信机制。它可以让一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个特殊的类型,也就是 channel 可发送数据的类型。一个可以发送 int 类型数据的 channel 一般写为 chan int

Go语言提倡使用通信的方法代替共享内存,当一个资源需要在 goroutine 之间共享时,channelgoroutine 之间架起了一个管道,并提供了确保同步交换数据的机制。声明channel时,需要指定将要被共享的数据的类型。可以通过channel共享内置类型、命名类型、结构类型和引用类型的值或者指针。

channel 数据结构如下:

核心包括一个 lock 控制并发, 等待发送的队列, 等待接收的队列, 队列大小, 队列元素指针, 是否关闭标识。

通信的方法就是使用通道(channel),如下图所示。

Go 中 Chanel 特性

  • 给一个 nil channel 发送数据,造成永远阻塞
  • 从一个 nil channel 接收数据,造成永远阻塞
  • 给一个已经关闭的 channel 发送数据,引起 panic
  • 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
  • 无缓冲的channel是同步的,而有缓冲的channel是非同步的

以上5个特性是死东西,也可以通过口诀来记忆:“空读写阻塞,写关闭异常,读关闭空零”。

代码语言:javascript
复制
package main

import (
 "fmt"
 "time"
)

func main() {
 ch := make(chan int, 1000)
 go func() {
  for i := 0; i < 10; i++ {
   ch <- i
  }
 }()
 go func() {
  for {
   a, ok := <-ch
   if !ok {
    fmt.Println("close")
    return
   }
   fmt.Println("a: ", a)
  }
 }()
 close(ch)
 fmt.Println("ok")
 time.Sleep(time.Second * 100)
}

15字口诀:“空读写阻塞,写关闭异常,读关闭空零”,往已经关闭的channel写入数据会panic的。因为main在开辟完两个goroutine之后,立刻关闭了ch, 结果:

代码语言:javascript
复制
ok
close
panic: send on closed channel

举例

发送数据

声明一个 channel

写入数据,更新 sendx 和 recvx

写满数据,更新 sendx 和 recvx

接收数据

读取一个数据,更新 sendx 和 recvx

参考资料

  • https://www.yuque.com/aceld/golang/ithv8f
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-09-19 19:54,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • golang channel
    • channel 数据结构如下:
    • Go 中 Chanel 特性
    • 举例
      • 发送数据
        • 接收数据
          • 参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档