golang的缓冲channel简单使用

目录

  • golang的缓冲channel简单使用

    • 阻塞型
    • 非阻塞

golang的缓冲channel简单使用



我们常用的是无缓冲channel :

make(chan type)

其实make() 创建chan的第二个参数可设置缓冲channel的大小。
上述语句等价于 make(chan type, 1) 即创建了一个缓冲区大小为1channel

下面看有缓冲channel的两个例子.

阻塞型

demo :
协程1 :每隔1s 往有10个缓冲的channel里面写一条msg,

协程2:每隔3s 取一条msg,

package main 

import(
    //"fmt"
    "time"
    "strconv"
    log "github.com/astaxie/beego/logs"
)

func main() {
    log.Debug("---main--- start")

    msgs := make(chan string, 10)

    i := 0

    go func() {
        time.Sleep(3*time.Second)

        for {
            time.Sleep(1*time.Second)
            i++
            msg := "msg " + strconv.Itoa(i)
            msgs <- msg
            log.Debug("------ put msg : ", msg)
        }
    }()

    go func() {

        for {

            get := <- msgs

            log.Debug("---------------- pop msg : ", get)

            time.Sleep(3*time.Second)
        }

    }()

    time.Sleep(100*time.Second)

}

可以看到当缓冲区满了以后,写channel的操作会阻塞在那里等待读端取走msg后才能写入。

非阻塞

实际场景中我们可能不希望程序阻塞,那么可以使用select来控制,当缓冲区满了后忽略该条msg继续执行我们的程序。

package main 

import(
    //"fmt"
    "time"
    "strconv"
    log "github.com/astaxie/beego/logs"
)

func main() {
    log.Debug("---main--- start")

    msgs := make(chan string, 3)

    i := 0

    go func() {
        time.Sleep(3*time.Second)

        for {

            time.Sleep(1*time.Second)
            i++
            msg := "msg " + strconv.Itoa(i)

            select {
                case msgs <- msg:
                    log.Debug("------ put msg : ", msg)
                default :
                    log.Debug("-----msgs chan cache full sleep 1s-----")
                    log.Debug("-----ignore this msg-----> : ", msg)
            }
        }
    }()

    go func() {

        for {

            get := <- msgs

            log.Debug("---------------- pop msg : ", get)

            time.Sleep(3*time.Second)
        }

    }()

    time.Sleep(100*time.Second)

}

可以看到,因为写端写入过快,再写入msg6时缓冲区已满,执行default丢弃了msg6,读端在取走msg5后, 取走的不是msg6,而是msg7

原文地址:https://www.cnblogs.com/ailumiyana/p/11108170.html

时间: 2024-10-07 09:59:19

golang的缓冲channel简单使用的相关文章

Golang并发中channel的分析

问题:面对并发问题,是用channel解决,还是用Mutex解决? 如果自己心里还没有清晰的答案,那就读下这篇文章,你会了解到: 使用channel解决并发问题的核心思路和示例 channel擅长解决什么样的并发问题,Mutex擅长解决什么样的并发问题 一个并发问题该怎么入手解解决 一个重要的plus思维 前戏 前面很多篇的文章都在围绕channel介绍,而只有前一篇sync的文章介绍到了Mutex,不是我偏心,而是channel在Golang是first class级别的,设计在语言特性中的,

go语音之进阶篇无缓冲channel

1.无缓冲channel 示例: package main import ( "fmt" "time" ) func main() { //创建一个无缓存的channel ch := make(chan int, 0) //len(ch)缓冲区剩余数据个数, cap(ch)缓冲区大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建协程 go func() { for

golang 初体验 - channel

channel 分为两种: 1. 无缓冲 channel 2. 缓冲 channel 无缓冲 channel 的使用必须遵循一个原则:推送和读取必须同时存在,否则就发生死锁 先上代码: 这里定义了一个 int 型的信道 c1,然后通过辅助协程并行给 c1 推送 v(就是 i)然后又在主协程读取. 输出: 有缓冲 channel 必须遵循一个原则:要确保 channel 缓冲的个数与推送.读取成比例 输出: 这里定义了一个缓冲区长度为3的 channel,然后推送3条消息,接着循环读取这个 cha

Golang中的channel代码示例----无缓冲、有缓冲、range、close

// code_043_channel_unbuffered project main.go package main import ( "fmt" "time" ) func main() { c := make(chan int, 0) //无缓冲的通道 //内置函数 len 返回未被读取的缓冲元素数量, cap 返回缓冲区大小 fmt.Printf("len(c)=%d, cap(c)=%d\n", len(c), cap(c)) go f

golang 如何查看channel通道中未读数据的长度

可以通过内建函数len查看channel中元素的个数. 内建函数len的定义如下: func len(v Type) int The len built-in function returns the length of v, according to its type: Array: the number of elements in v.数组中元素的个数 Pointer to array: the number of elements in *v (even if v is nil).数组中

GO (channel简单使用篇)

//1. 定义一组channel ch := make(chan bool) //chan接收类型为bool 后还有一个参数为缓存参数本篇不讲解缓存(这一行不在代码范围内) //定义函数使用 func main(){ ch := make(chan bool) go Task(ch) <- ch close(ch) //关闭指令 } func Task(){ fmt.Println("Go Task") ch<-true //ch接到 true指令,把数据 GoTask 存

从零开始用golang创建一条简单的区块链

区块链(Blockchain),是比特币的一个重要概念,它本质上是一个去中心化的数据库,同时作为比特币的底层技术,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次比特币网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块.(百度百科)        区块链本身的结构是非常简单的,其复杂的部分在于他的共识机制,加密等部分.我们可以将区块链看做一种数据结构,顾名思义,区块链就是把许多个区块(Block)链接在一起,成为一个链式结构(Chain).所以我们要做的事情也很简单

golang goroutine、channel和select

goroutine package main import "fmt" import "time" func printn(id int){ for i := 0;i<10;i++ { fmt.Println(id,":",i) } } func main(){ for i :=0;i<5;i++ { go printn(i) } fmt.Println("waiting...") time.Sleep(time.

golang for thread channel routine consumer and producer

package main import "time" func testThread(){ i:=3 go func(a int){ println(a) println("this is go func!") }(i) time.Sleep(1*time.Second) println("hello main thread!") } func testChannel(){ //read write channel ch:=make(chan i