Go语言的通道(2)-缓冲通道
有缓冲的通道相比于无缓冲通道,多了一个缓存的功能,如下图描述的一样:
从图上可以明显看到和无缓冲通道的区别,无缓冲必须两个Goroutine都进入通道才能进行数据的交换,这个不用,如果数据有,直接就能拿走。
package ChannelDemo import (
"fmt"
"math/rand"
"sync"
"time"
) const (
numberGoroutines =
taskLoad =
) var bufferWg sync.WaitGroup func init() {
rand.Seed(time.Now().Unix())
} func main() {
//创建了一个10任务的缓冲通道
tasks := make(chan string, taskLoad)
bufferWg.Add(numberGoroutines) //创建4个Goroutine
for gr := ; gr <= numberGoroutines; gr++ {
go worker(tasks, gr)
} //向缓冲通道中放入数据
for post := ; 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()
time.Sleep(time.Duration(sleep) * time.Millisecond) fmt.Printf("Worker: %d : 完成工作 %s\n", worker, task)
}
}
运行结果:
Worker: : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 开始工作 Task :
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作
Worker: : 完成工作 Task :
Worker: : 结束工作
因为哪一个worker先从通道中取值有系统自己进行调度的,所以每次运行的结果稍微不同,但是相同的是10个任务被4个协程有条不紊的完成了
注意:main中有一句代码 Close(tasks) 关闭通道的代码非常重要。当通道关闭后,goroutine 依旧可以从通道接收数据,但是不能再向通道里发送数据。
能够从已经关闭的通道接收数据这一点非常重要,因为这允许通道关闭后依旧能取出其中缓冲的全部值,而不会有数据丢失.
五、总结
无缓冲的通道保证同时交换数据,而有缓冲的通道不做这种保证。
Go语言的通道(2)-缓冲通道的更多相关文章
- Go语言的通道(1)-无缓冲通道
前言: 上文中我们采用了[原子函数]已经[共享锁]两种方式分别对多个goroutine进行了同步,但是在go语言中提供了另一种更好的方式,那就是使用通道(Channel). 一.通道是什么? 其实无论 ...
- golang channel无缓冲通道会发生阻塞的验证
公司搞了午间技术par,本周我讲的主题是关于无缓冲通道channel是否会发生阻塞,并进行了验证. go语言中channel分为无缓冲通道和有缓冲通道两种 channel提供了一种在goroutine ...
- [Go] golang无缓冲通道实现工作池控制并发
展示如何使用无缓冲的通道创建一个goroutine池,控制并发频率1.无缓冲通道保证了两个goroutine之间的数据交换2.当所有的goroutine都忙的时候,能够及时通过通道告知调用者3.无缓冲 ...
- [Go] golang缓冲通道实现资源池
go的pool资源池:1.当有多个并发请求的时候,比如需要查询数据库2.先创建一个2个容量的数据库连接资源池3.当一个请求过来的时候,去资源池里请求连接资源,肯定是空的就创建一个连接,执行查询,结束后 ...
- [Go] golang缓冲通道实现管理一组goroutine工作
通道1.当一个资源需要在goroutine之间共享时,通道在goroutine之间架起了一个管道2.无缓冲通道和有缓冲通道,make的第二个参数就是缓冲区大小3.无缓冲通道需要发送和接收都准备好,否则 ...
- Golang并发编程有缓冲通道和无缓冲通道(channel)
无缓冲通道 是指在接收前没有能力保存任何值得通道.这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作.如果两个goroutine没有同时准备好,通道会导 ...
- [GO]有缓冲通道
有缓冲通道就是在有能力保留数据的通道,那么通道在满的时候或者通道是空的时候,存数据和取数据就会发生阻塞 package main import ( "fmt" "time ...
- [GO]无缓冲通道(unbuffered channel)
无缓冲通道(unbuffered channel)是指在接收前没有能力保存任何值的通道,在之前的例子中使用的都是无缓冲通道,需要注意的是,对于无缓冲通道而言,不管是往通道里写数据还是从通道里读数据,都 ...
- [Golang]-5 协程、通道及其缓冲、同步、方向和选择器
目录 协程 通道 通道缓冲 通道同步 通道方向 通道选择器 协程 Go 协程 在执行上来说是轻量级的线程. 代码演示 import ( "fmt" "time" ...
随机推荐
- NLP&深度学习:近期趋势概述
NLP&深度学习:近期趋势概述 摘要:当NLP遇上深度学习,到底发生了什么样的变化呢? 在最近发表的论文中,Young及其同事汇总了基于深度学习的自然语言处理(NLP)系统和应用程序的一些最新 ...
- redis 慢日志查询
Intro 可能有一些命令需要很长时间才能在redis服务器上处理,导致请求超时. 长时间运行的命令的很少例子有 mget有大量的键,键*或写得不好的lua脚本. 可以运行通过 SlowLog 命令查 ...
- JMeter接口测试 (二) ~ 参数化
对应qq群号:616961231 上篇内容介绍了jmeter的基本使用, 略微提了如何做参数化, 本篇对参数化做进一步深入讲解, 参数化可以将一个变量使用不同数据, 比如有多个用户下单购买商品,调用 ...
- centos7 安装java运行环境
1.检测是否存在相关历史版本 shell:java-version 1.1.存在相关OpenJDK和其他版本SDK则需要删除,如图. 查看详细信息,命令窗口输入,shell:rpm -qa | gre ...
- python 通过元类控制类的创建
一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...
- 【学习】Linux Shell脚本实例之一
1.程序流程控制实例 程序流程控制,实际上就是改变程序的执行顺序.程序在执行过程中若流程被改变,就可能导致输出不同,因此利用这一特性就能够实现程序执行结果的控制.程序流程控制可分为“选择”和“循环”这 ...
- An Overview of End-to-End Exactly-Once Processing in Apache Flink (with Apache Kafka, too!)
01 Mar 2018 Piotr Nowojski (@PiotrNowojski) & Mike Winters (@wints) This post is an adaptation o ...
- There Are Now 3 Apache Spark APIs. Here’s How to Choose the Right One
See Apache Spark 2.0 API Improvements: RDD, DataFrame, DataSet and SQL here. Apache Spark is evolvin ...
- hadoop dfs.datanode.du.reserved 预留空间配置方法
对于datanode配置预留空间的方法 为:在hdfs-site.xml添加如下配置 <property> <name>dfs.datanode.du.reserved< ...
- linux vi粘贴格式易错乱
对于一些冗长的代码完全可以粘贴的时候,vi粘贴所有格式全部错乱,完全无法阅读. 解决办法:esc进入命令行模式后,输入 :set paste,然后再i进入粘贴编辑模式,即可正常复制并保留原有格式-