博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言的通道(2)-缓冲通道
阅读量:6608 次
发布时间:2019-06-24

本文共 1965 字,大约阅读时间需要 6 分钟。

有缓冲的通道相比于无缓冲通道,多了一个缓存的功能,如下图描述的一样:

从图上可以明显看到和无缓冲通道的区别,无缓冲必须两个Goroutine都进入通道才能进行数据的交换,这个不用,如果数据有,直接就能拿走。

package ChannelDemoimport (    "fmt"    "math/rand"    "sync"    "time")const (    numberGoroutines = 4    taskLoad         = 10)var bufferWg sync.WaitGroupfunc init() {    rand.Seed(time.Now().Unix())}func main() {    //创建了一个10任务的缓冲通道    tasks := make(chan string, taskLoad)    bufferWg.Add(numberGoroutines)    //创建4个Goroutine    for gr := 1; gr <= numberGoroutines; gr++ {        go worker(tasks, gr)    }    //向缓冲通道中放入数据    for post := 1; post <= taskLoad; post++ {        tasks <- fmt.Sprintf("Task : %d", post)    }    close(tasks)    bufferWg.Wait()}func worker(tasks chan string, worker int) {    defer bufferWg.Done()    for {        task, ok := <-tasks        if !ok {            fmt.Printf("Worker: %d : 结束工作 \n", worker)            return        }        fmt.Printf("Worker: %d : 开始工作 %s\n", worker, task)        //随机处理一下工作的时间        sleep := rand.Int63n(100)        time.Sleep(time.Duration(sleep) * time.Millisecond)        fmt.Printf("Worker: %d : 完成工作 %s\n", worker, task)    }}

运行结果:

Worker: 3 : 开始工作 Task : 4Worker: 2 : 开始工作 Task : 2Worker: 1 : 开始工作 Task : 1Worker: 4 : 开始工作 Task : 3Worker: 4 : 完成工作 Task : 3Worker: 4 : 开始工作 Task : 5Worker: 2 : 完成工作 Task : 2Worker: 2 : 开始工作 Task : 6Worker: 3 : 完成工作 Task : 4Worker: 3 : 开始工作 Task : 7Worker: 1 : 完成工作 Task : 1Worker: 1 : 开始工作 Task : 8Worker: 3 : 完成工作 Task : 7Worker: 3 : 开始工作 Task : 9Worker: 1 : 完成工作 Task : 8Worker: 1 : 开始工作 Task : 10Worker: 4 : 完成工作 Task : 5Worker: 4 : 结束工作Worker: 3 : 完成工作 Task : 9Worker: 3 : 结束工作Worker: 2 : 完成工作 Task : 6Worker: 2 : 结束工作Worker: 1 : 完成工作 Task : 10Worker: 1 : 结束工作

因为哪一个worker先从通道中取值有系统自己进行调度的,所以每次运行的结果稍微不同,但是相同的是10个任务被4个协程有条不紊的完成了

注意:main中有一句代码 Close(tasks) 关闭通道的代码非常重要。当通道关闭后,goroutine 依旧可以从通道接收数据,但是不能再向通道里发送数据。

能够从已经关闭的通道接收数据这一点非常重要,因为这允许通道关闭后依旧能取出其中缓冲的全部值,而不会有数据丢失.

 

五、总结

无缓冲的通道保证同时交换数据,而有缓冲的通道不做这种保证。

转载于:https://www.cnblogs.com/dcz2015/p/10384067.html

你可能感兴趣的文章
mysql设置字符集CHARACTER SET
查看>>
redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换
查看>>
log框架集成
查看>>
python命令行下安装redis客户端
查看>>
如何在Oracle中复制表结构和表数据
查看>>
[河南省ACM省赛-第四届] 序号互换 (nyoj 303)
查看>>
3 Oracle 32位客户端安装及arcgis连接
查看>>
[MFC] MFC编译程序,缺少MFC动态链接库的解决
查看>>
Android进阶2之APK方式换肤
查看>>
Sticker.js – 帮助你在网站中加入贴纸效果
查看>>
命名参数
查看>>
windows服务与计划任务
查看>>
重新想象 Windows 8 Store Apps (8) - 控件之 WebView
查看>>
JAVA中的File类
查看>>
java控制台输入
查看>>
欧拉路与欧拉回路的性质
查看>>
ESET Smart Security 免费60天
查看>>
初识MVCSharp
查看>>
90后黄金程序员,你不是码农,请自信
查看>>
Android四大基本组件介绍与生命周期
查看>>