美文网首页
有缓存channel

有缓存channel

作者: 测试探索 | 来源:发表于2020-08-17 06:40 被阅读0次
有缓冲的通道

是一种在被接收前能够存储一个或多个值的通道
  这种类型的通道并不强制要求goroutine之间必须同时完成发送和接收。通道会阻塞发送和接收动作的条件也不同。只有在通道中人没有要接收的值时,接收动作才会阻塞。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。
 &ensp这导致有缓冲的通道和无缓冲的通道之间一个很大的不同,无缓冲的通道保证进行发送和接收的goroutine会在同一时间进行数据交换;有缓冲的通道没有这种保证。


有缓存的channel
通过图片了解无缓存的channel

第一步:右侧的goroutine正在从通道接收一个值。
第二步:右侧的这个goroutine独立完成了接收值得动作,而左侧的goroutine正在发送一个新值到通道里。
第三本步:左侧的goroutine还在向通道发送新值,而右侧的goroutine正在从通道接收另外一个值,这个步骤里的两个操作既不是同步,也不会互相阻塞。
第四步:所有的发送和接收都完成,而通道里还有几个值,也有一些空间可以存更多的值。

有缓存的channel创建格式
make(chan Type,capacity)
package main

import (
    "fmt"
    "time"
)

func main() {
    //创建一个有缓存的channel
    ch := make(chan int, 3)

    //len(ch)缓冲区剩余数据个数,cap(ch)缓冲区大小
    fmt.Printf("len(ch) = %d , cap(ch) = %d \n", len(ch), cap(ch))

    //新建协程
    go func() {
        for i := 0; i < 3; i++ {
            ch <- i //往chan写内容
            fmt.Printf("子协程[%d]:len(ch) = %d,cap(ch) = %d\n", i, len(ch), cap(ch))

        }
    }()

    //延时
    time.Sleep(2 * time.Second)

    for i := 0; i < 3; i++ {
        num := <-ch //读管道中内容,没有内容前,阻塞
        fmt.Println("num = ", num)
    }
}
#结果,运行更能看出效果,尤其是主协程受延时的影响
len(ch) = 0 , cap(ch) = 3 
子协程[0]:len(ch) = 1,cap(ch) = 3
子协程[1]:len(ch) = 2,cap(ch) = 3
子协程[2]:len(ch) = 3,cap(ch) = 3
num =  0
num =  1
num =  2

容量与延时,与阻塞的关系

package main

import (
    "fmt"
    "time"
)

func main() {
    //创建一个有缓存的channel
    ch := make(chan int, 3)

    //len(ch)缓冲区剩余数据个数,cap(ch)缓冲区大小
    fmt.Printf("len(ch) = %d , cap(ch) = %d \n", len(ch), cap(ch))

    //新建协程
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i //往chan写内容
            fmt.Printf("子协程[%d]:len(ch) = %d,cap(ch) = %d\n", i, len(ch), cap(ch))

        }
    }()

    //延时
    time.Sleep(2 * time.Second)

    for i := 0; i < 10; i++ {
        num := <-ch //读管道中内容,没有内容前,阻塞
        fmt.Println("num = ", num)
    }
}
#结果
len(ch) = 0 , cap(ch) = 3 
子协程[0]:len(ch) = 1,cap(ch) = 3
子协程[1]:len(ch) = 2,cap(ch) = 3
子协程[2]:len(ch) = 3,cap(ch) = 3
num =  0
num =  1
num =  2
num =  3
子协程[3]:len(ch) = 3,cap(ch) = 3
num =  4
子协程[4]:len(ch) = 0,cap(ch) = 3
子协程[5]:len(ch) = 0,cap(ch) = 3
num =  5
num =  6
子协程[6]:len(ch) = 1,cap(ch) = 3
子协程[7]:len(ch) = 0,cap(ch) = 3
子协程[8]:len(ch) = 1,cap(ch) = 3
子协程[9]:len(ch) = 2,cap(ch) = 3
num =  7
num =  8
num =  9

相关文章

  • 有缓存channel

    有缓冲的通道 是一种在被接收前能够存储一个或多个值的通道  这种类型的通道并不强制要求goroutine之间必须同...

  • Spring AMQP学习笔记

    Spring的CachingConnectionFactory用于缓存Channel。 The purpose o...

  • Go语言学习教程(十六)

    一、死锁 * 在主goroutine中向无缓存channel添加内容或在主goroutine中向channel添加...

  • golang 中channel 缓存channel 和无缓存ch

    无缓冲的 不仅仅是 向 c1 通道放 1 而是 一直要有别的携程 <-c1 接手了 这个参数,那么c1<-1才会继...

  • golang作业帮面试

    1.channel实现 go调度原理 select和epoll的区别 redis分布式锁 redis缓存穿透,缓存...

  • 无缓存的channel

    无缓存的通道   是指在接收前没有能力保存任何值的通道  这种类型的通道要求goroutine和接收gorouti...

  • Golang无限缓存channel

    需求 最近在弄一个游戏的gate网关转发服务器,服务器之间使用的是nats通讯,gate的作用是接收客户端发来的消...

  • 开发速记-emacs篇: haskell+nix开发模式

    安装nix并配置channel: 安装cachix 并配置iohk缓存 安装cabal 安装emacs 配置ema...

  • golang 无缓存channel实现原子锁

    用一个缓存空间的channel实现锁比较简单,如果是无缓存就会稍微麻烦点直接上代码了: 以下是sample: 欢迎...

  • Introduce

    nsq_to_file只是一个普通的消费者,获取消息缓存到磁盘topic 和 channel名字是否合法:

网友评论

      本文标题:有缓存channel

      本文链接:https://www.haomeiwen.com/subject/rnysdktx.html