详解golang channel有无缓冲区的区别

 更新时间:2024年01月29日 10:47:07   作者:壮Sir不壮  
这篇文章主要给大家介绍了golang channel有无缓冲区的区别,无缓冲是同步的,有缓冲是异步的,文中通过代码示例给大家讲解的非常详细,需要的朋友可以参考下

有无缓冲的区别

形象说明一下无缓冲和有缓冲的区别:

无缓冲是同步的,例如 make(chan int),就是一个送信人去你家门口送信,你不在家他不走,你一定要接下信,他才会走,无缓冲保证信能到你手上。

有缓冲是异步的,例如 make(chan int, 1),就是一个送信人去你家仍到你家的信箱,转身就走,除非你的信箱满了,他必须等信箱空下来,有缓冲的保证信能进你家的邮箱。

channel 无缓冲

例1:

func main() {
    ch := make(chan int)
    ch <- 1 // 报错,因为ch 无缓冲,存一个就必须立即取出来
    fmt.Println(<- ch)
}

改正:

func main() {
    ch := make(chan int)
    go tt(ch) // 开一个 goroutine
    fmt.Println("我先执行1111")
    fmt.Println(<-ch) // 因为前面开了一个 goroutine, 这一行比 go tt(ch) 先执行,这里堵塞了,等到 tt(ch) 中的语句执行完之后,本行执行
    // 我先执行1111
    // 我先执行2222
    // 1
}
 
func tt(ch chan int) {
    fmt.Println("我先执行2222")
    ch <- 1
}

例2:

package main
 
import "fmt"
 
func main() {
    ch := make(chan int) // 无缓冲的channel
    go unbufferChan(ch)
 
    for i := 0; i < 10; i++ {
        fmt.Println("receive ", <-ch) // 读出值
    }
}
 
func unbufferChan(ch chan int) {
    for i := 0; i < 10; i++ {
        fmt.Println("send ", i)
        ch <- i // 写入值
    }
}
 
// 输出
// send  0
// send  1
// receive  0
// receive  1
// send  2
// send  3
// receive  2
// receive  3
// send  4
// send  5
// receive  4
// receive  5
// send  6
// send  7
// receive  6
// receive  7
// send  8
// send  9
// receive  8
// receive  9

channel 带缓存

例1:

放的速度较快,先放满了 5 个,阻塞住;取的速度较慢,放了5个才开始取,由于缓冲区已经满了,所以取出一个之后,才能再次放入;放完了之后虽然缓冲区关闭了,但是缓冲区的内容还保留,所以还能继续取出

func put(c chan int) {
    for i := 0; i < 10; i++ {
       c <- i
       time.Sleep(100 * time.Millisecond)
       fmt.Println("->放入", i)
    }
    fmt.Println("=所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。")
    close(c)
}
 
func main() {
    ch := make(chan int, 5)
    go put(ch)
    for {
       time.Sleep(1000 * time.Millisecond)
       data, ok := <-ch
       if ok == true {
          fmt.Println("<-取出", data)
       } else {
          break
       }
    }
}
 
// ->放入 0
// ->放入 1
// ->放入 2
// ->放入 3
// ->放入 4
// <-取出 0
// ->放入 5
// <-取出 1
// ->放入 6
// <-取出 2
// ->放入 7
// <-取出 3
// ->放入 8
// <-取出 4
// ->放入 9
// =所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。
// <-取出 5
// <-取出 6
// <-取出 7
// <-取出 8
// <-取出 9

例2:一边存,一边取

package main
 
import"fmt"
 
var c = make(chan int, 5)
 
func main() {
    go worker(1)
    for i := 1; i < 10; i++ {
       c <- i
       fmt.Println(i)
       fmt.Println("cap = ", cap(c), " len = ", len(c))
    }
}
 
func worker(id int) {
    for {
       _ = <-c
    }
}
 
// 运行输出:
// 1
// cap =  5  len =  0
// 2
// cap =  5  len =  0
// 3
// cap =  5  len =  1
// 4
// cap =  5  len =  2
// 5
// cap =  5  len =  0
// 6
// cap =  5  len =  1
// 7
// cap =  5  len =  2
// 8
// cap =  5  len =  2
// 9
// cap =  5  len =  0

到此这篇关于详解golang channel有无缓冲区的区别的文章就介绍到这了,更多相关golang channel缓冲区内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go语言实现markdown解析库的方法示例

    go语言实现markdown解析库的方法示例

    这篇文章主要介绍了go语言实现markdown解析库的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • go 字符串修改的操作代码

    go 字符串修改的操作代码

    这篇文章主要介绍了go 字符串修改,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Go语言等待组sync.WaitGrou的使用示例

    Go语言等待组sync.WaitGrou的使用示例

    本文主要介绍了Go语言等待组sync.WaitGrou的使用示例,sync.WaitGroup只有3个方法,Add(),Done(),Wait(),下面就来具体的介绍一下如何使用,感兴趣的可以了解一下
    2024-08-08
  • Go基础教程系列之回调函数和闭包详解

    Go基础教程系列之回调函数和闭包详解

    这篇文章主要介绍了Go基础教程系列之回调函数和闭包详解,需要的朋友可以参考下
    2022-04-04
  • Golang数据类型比较详解

    Golang数据类型比较详解

    这篇文章主要围绕Golang数据类型比较详细展开,文中有详细的比较过程,需要的朋友可以参考一下
    2023-04-04
  • golang结合mysql设置最大连接数和最大空闲连接数

    golang结合mysql设置最大连接数和最大空闲连接数

    本文介绍golang 中连接MySQL时,如何设置最大连接数和最大空闲连接数,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 一文初探Go语言中的reflect反射包

    一文初探Go语言中的reflect反射包

    这篇文章主要和大家分享一下Go语言中的reflect反射包,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的小伙伴可以参考一下
    2022-12-12
  • Go语言中常用语法编写与优化技巧小结

    Go语言中常用语法编写与优化技巧小结

    为了充分利用 Go 的潜力,我们需要了解如何优化 Go 程序,本文将介绍一些常见的 Go 语言优化技巧,并通过实际例子进行说明,希望对大家有所帮助
    2024-02-02
  • GO语言实现TCP服务器的示例代码

    GO语言实现TCP服务器的示例代码

    这篇文章主要为大家详细介绍了如何通过GO语言实现TCP服务器,文中的示例代码讲解详细,对我们深入了解Go语言有一定的帮助,需要的可以参考一下
    2023-03-03
  • goland 实现自动格式化代码

    goland 实现自动格式化代码

    这篇文章主要介绍了goland 实现自动格式化代码的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04

最新评论