设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间21 现在时间21 缓存数据 青春之所以让人留念,是因为我们年轻时干的蠢事大都妙不可言。晚安!

青春之所以让人留念,是因为我们年轻时干的蠢事大都妙不可言。晚安!

查看: 636|回复: 1

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

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:233
  • 打卡月天数:1
  • 打卡总奖励:3554
  • 最近打卡:2025-07-01 22:19:44
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
372
主题
347
精华
0
金钱
4669
积分
790
注册时间
2022-12-30
最后登录
2025-7-1

发表于 2024-2-25 16:43:19 | 显示全部楼层 |阅读模式
目录


  • 有无缓冲的区别
  • channel 无缓冲

    • 例1:
    • 例2:

  • channel 带缓存

    • 例1:
    • 例2:一边存,一边取


有无缓冲的区别

形象说明一下无缓冲和有缓冲的区别:
无缓冲是同步的,例如 make(chan int),就是一个送信人去你家门口送信,你不在家他不走,你一定要接下信,他才会走,无缓冲保证信能到你手上。
有缓冲是异步的,例如 make(chan int, 1),就是一个送信人去你家仍到你家的信箱,转身就走,除非你的信箱满了,他必须等信箱空下来,有缓冲的保证信能进你家的邮箱。

channel 无缓冲



例1:
  1. func main() {
  2.     ch := make(chan int)
  3.     ch <- 1 // 报错,因为ch 无缓冲,存一个就必须立即取出来
  4.     fmt.Println(<- ch)
  5. }
复制代码
改正:
  1. func main() {
  2.     ch := make(chan int)
  3.     go tt(ch) // 开一个 goroutine
  4.     fmt.Println("我先执行1111")
  5.     fmt.Println(<-ch) // 因为前面开了一个 goroutine, 这一行比 go tt(ch) 先执行,这里堵塞了,等到 tt(ch) 中的语句执行完之后,本行执行
  6.     // 我先执行1111
  7.     // 我先执行2222
  8.     // 1
  9. }

  10. func tt(ch chan int) {
  11.     fmt.Println("我先执行2222")
  12.     ch <- 1
  13. }
复制代码
例2:
  1. package main

  2. import "fmt"

  3. func main() {
  4.     ch := make(chan int) // 无缓冲的channel
  5.     go unbufferChan(ch)

  6.     for i := 0; i < 10; i++ {
  7.         fmt.Println("receive ", <-ch) // 读出值
  8.     }
  9. }

  10. func unbufferChan(ch chan int) {
  11.     for i := 0; i < 10; i++ {
  12.         fmt.Println("send ", i)
  13.         ch <- i // 写入值
  14.     }
  15. }

  16. // 输出
  17. // send  0
  18. // send  1
  19. // receive  0
  20. // receive  1
  21. // send  2
  22. // send  3
  23. // receive  2
  24. // receive  3
  25. // send  4
  26. // send  5
  27. // receive  4
  28. // receive  5
  29. // send  6
  30. // send  7
  31. // receive  6
  32. // receive  7
  33. // send  8
  34. // send  9
  35. // receive  8
  36. // receive  9
复制代码
channel 带缓存

例1:

放的速度较快,先放满了 5 个,阻塞住;取的速度较慢,放了5个才开始取,由于缓冲区已经满了,所以取出一个之后,才能再次放入;放完了之后虽然缓冲区关闭了,但是缓冲区的内容还保留,所以还能继续取出
  1. func put(c chan int) {
  2.     for i := 0; i < 10; i++ {
  3.        c <- i
  4.        time.Sleep(100 * time.Millisecond)
  5.        fmt.Println("->放入", i)
  6.     }
  7.     fmt.Println("=所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。")
  8.     close(c)
  9. }

  10. func main() {
  11.     ch := make(chan int, 5)
  12.     go put(ch)
  13.     for {
  14.        time.Sleep(1000 * time.Millisecond)
  15.        data, ok := <-ch
  16.        if ok == true {
  17.           fmt.Println("<-取出", data)
  18.        } else {
  19.           break
  20.        }
  21.     }
  22. }

  23. // ->放入 0
  24. // ->放入 1
  25. // ->放入 2
  26. // ->放入 3
  27. // ->放入 4
  28. // <-取出 0
  29. // ->放入 5
  30. // <-取出 1
  31. // ->放入 6
  32. // <-取出 2
  33. // ->放入 7
  34. // <-取出 3
  35. // ->放入 8
  36. // <-取出 4
  37. // ->放入 9
  38. // =所有的都放进去了!关闭缓冲区,但是里面的数据不会丢失,还能取出。
  39. // <-取出 5
  40. // <-取出 6
  41. // <-取出 7
  42. // <-取出 8
  43. // <-取出 9
复制代码
例2:一边存,一边取
  1. package main

  2. import"fmt"

  3. var c = make(chan int, 5)

  4. func main() {
  5.     go worker(1)
  6.     for i := 1; i < 10; i++ {
  7.        c <- i
  8.        fmt.Println(i)
  9.        fmt.Println("cap = ", cap(c), " len = ", len(c))
  10.     }
  11. }

  12. func worker(id int) {
  13.     for {
  14.        _ = <-c
  15.     }
  16. }

  17. // 运行输出:
  18. // 1
  19. // cap =  5  len =  0
  20. // 2
  21. // cap =  5  len =  0
  22. // 3
  23. // cap =  5  len =  1
  24. // 4
  25. // cap =  5  len =  2
  26. // 5
  27. // cap =  5  len =  0
  28. // 6
  29. // cap =  5  len =  1
  30. // 7
  31. // cap =  5  len =  2
  32. // 8
  33. // cap =  5  len =  2
  34. // 9
  35. // cap =  5  len =  0
复制代码
到此这篇关于详解golang channel有无缓冲区的区别的文章就介绍到这了,更多相关golang channel缓冲区内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
13
积分
6
注册时间
2022-12-29
最后登录
2022-12-29

发表于 2025-4-4 05:38:37 | 显示全部楼层
感谢楼主,顶。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表