Go 缓冲信道
缓冲信道
语法结构:cap为容量
ch := make(chan type, cap)
- 缓冲信道支持len()和cap()。
- 只能向缓冲信道发送容量以内的数据。
- 只能接收缓冲信道长度以内的数据。
- 缓冲信道的容量是指信道可以存储的值的数量。我们在使用 make 函数创建缓冲信道的时候会指定容量大小。
- 缓冲信道的长度是指信道中当前排队的元素个数。
信道是异步的,是一种在被创建时就被开辟了能存储一个或者多个值的信道。
这种类型并不要求发送与接收同时进行。只要缓冲区有未使用空间用于发送数据,或还包含可以接收的数据,那么其通信就会无阻塞地进行。只有在通道中没有要接收的值时,接收动作才会阻塞。
示例一
package main
import (
"fmt"
)
func main() {
//创建一个容量为3的缓冲信道
ch := make(chan string, 3)
ch <- "naveen"
ch <- "paul"
fmt.Println("capacity is", cap(ch)) //capacity is 3
fmt.Println("length is", len(ch)) //length is 2
fmt.Println("read value", <-ch) //read value naveen
fmt.Println("new length is", len(ch)) //new length is 1
}
示例二
package main
import (
"fmt"
"time"
)
func write(ch chan int) {
for i := 0; i < 5; i++ {
ch <- i
fmt.Println("successfully wrote", i, "to ch")
}
close(ch)
} func main() {
ch := make(chan int, 2)
go write(ch)
time.Sleep(2 * time.Second)
for v := range ch {
fmt.Println("read value", v,"from ch")
time.Sleep(2 * time.Second)
}
}
创建一个两个容量的信道。
write协程先向信道里写入两个数据,然后阻塞,并打印,主协程睡眠两秒。
两秒后,主协程从信道中读取一个数据,并睡眠两秒,此时write协程继续向信道里写入一个数据,然后阻塞,等待主协程两秒后读取数据。
死锁
package main
import (
"fmt"
)
func main() {
ch := make(chan string, 2)
ch <- "naveen"
ch <- "paul"
ch <- "steve"
fmt.Println(<-ch)
fmt.Println(<-ch)
}
当我们向信道写入数据时,超出了信道的容量,因此写入发生了阻塞。现在想要写操作能够进行下去,必须要有其它协程来读取这个信道的数据。
但在程序中,并没有并发协程来读取这个信道,因此这里会发生死锁(deadlock)。
WaitGroup
假设我们有 3 个并发执行的 Go 协程(由Go 主协程生成)。Go 主协程需要等待这 3 个协程执行结束后,才会终止。这就可以用 WaitGroup 来实现。
package main import (
"fmt"
"sync"
"time"
) func process(i int, wg *sync.WaitGroup) {
fmt.Println("started Goroutine ", i)
time.Sleep(2 * time.Second)
fmt.Printf("Goroutine %d ended\n", i)
//Done方法减少WaitGroup计数器的值,应在线程的最后执行。
wg.Done()
} /*
WaitGroup用于等待一组线程的结束。
父线程调用Add方法来设定应等待的线程的数量。
每个被等待的线程在结束时应调用Done方法。
同时,主线程里可以调用Wait方法阻塞至所有线程结束。
*/
func main() {
no := 3
var wg sync.WaitGroup
//并发协程
for i := 0; i < no; i++ {
/*
Add方法向内部计数加上delta,delta可以是负数;
如果内部计数器变为0,Wait方法阻塞等待的所有线程都会释放,
如果计数器小于0,方法panic。
*/
wg.Add(1)
go process(i, &wg)
}
//Wait方法阻塞直到WaitGroup计数器减为0。
wg.Wait()
fmt.Println("over")
}
Go 缓冲信道的更多相关文章
- Go 缓冲信道和非缓冲信道
非缓冲信道是一个进一个出,再一个进再一个出,信道内是不保存数据的 缓冲信道是可以很多个依次进去,存储在信道里,然后一个一个的按次序取出来. 不过缓冲信道如果超过了预期的存入个数,会发生信道阻塞,只有把 ...
- Go-并发和并行-协程-信道-缓冲信道-select-mutex-读写文件-beego框架
并发 Go 是并发式语言,而不是并行式语言.在讨论 Go 如何处理并发之前,我们必须理解何为并发,以及并发与并行的区别. 并发是什么? 并发是指立即处理多个任务的能力.一个CPU的情况下<意指看 ...
- Golang教程:goroutine信道
在上一篇教程中,我们讨论了如何使用协程实现并发.在这篇教程中,我们将讨论信道以及如何使用信道实现协程间通信. 什么是信道 信道(Channel)可以被认为是协程之间通信的管道.与水流从管道的一端流向另 ...
- Go 信道Channel
信道(Channel) 信道(Channel)可以被认为是协程之间通信的管道.数据可以从信道的一端发送并在另一端接收. 默认为同步模式,需要发送和接收配对.否则会被阻塞,直到另外的信道准备好后被唤醒. ...
- Go语言之Goroutine与信道、异常处理
一.Goroutine Go 协程可以看做成一个轻量级的线程,Go 协程相比于线程的优势: Goroutine 的成本更低大小只有 2 kb 左右,线程有几个兆. Goroutine 会复用线程,比如 ...
- 有关golang信道的面试笔记
信道是一个goroutine之间很关键的通信媒介. 理解golang的信道很重要,这里记录平时易忘记的.易混淆的点. 1. 基本使用 刚声明的信道,零值为nil,无法直接使用,需配合make函数进行初 ...
- go并发3
Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于Goroutine的PPT:https://talks.golang.org/2012/concurrency.s ...
- go并发
Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据. 以下是我入门的学习笔记. 首先,并行!=并发, 两者是不同的,可 ...
- Go语言并发与并行学习笔记(三)
转:http://blog.csdn.net/kjfcpua/article/details/18265475 Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于G ...
随机推荐
- flutter showDatePicker显示中文日期_Flutter时间控件显示中文
flutter showDatePicker showTimePicker显示中文日期 1.配置flutter_localizations依赖 找到pubspec.yaml配置flutter_loca ...
- 阶段5 3.微服务项目【学成在线】_day07 课程管理实战_03-新增课程-课程分类查询
2 新增课程 2.1 需求分析 用户操作流程如下: 1.用户进入“我的课程”页面,点击“新增课程”,进入新增课程页面 2.填写课程信息,选择课程分类.课程等级.学习模式等. 3.信息填写完毕,点击“提 ...
- jmeter 随机取一个值的方法
1.添加用户自定义变量 在要用到随机值的地方写入 ${__RandomFromMultipleVars(1|2|0)} 例子: 效果:
- Linux -- PHP-FPM的源码解析和模型
1.进程管理模式 PHP-FPM由1个master进程和N个worker进程组成.其中,Worker进程由master进程fork而来. PHP-FPM有3种worker进程管理模式. 1. Stat ...
- juc多线程编程学习
JUC是java.util.concurrent的缩写,java.util.concurrent是在并发编程中使用的工具类. 在以前的解决并发问题,一般是通过Synchronize关键字,现在可以通过 ...
- poj1584(判断凸包+求点到线段的距离)
题目链接:https://vjudge.net/problem/POJ-1584 题意:首先要判断凸包,然后判断圆是否在多边形中. 思路: 判断凸包利用叉积,判断圆在多边形首先要判断圆心是否在多边形中 ...
- 第三坑:jar包编译版本
这个是之前往was上发应用的时候踩的一个坑,当时我们知道was的jdk版本是1.6,然后我们是用1.7的jdk,编译版本选的是1.6,然后放上去不对,我们以为是编译的问题,然后又下载了1.6的jdk, ...
- 资源|《美团机器学习实践》PDF+思维导图
今天再给大家推荐一本由美团算法团队出版的<美团机器学习实践>,下载链接见文末. 美团算法团队由数百名优秀算法工程师组成,负责构建美团这个生活服务互联网大平台的"大脑", ...
- 1264: 祈雨(Java)
WUSTOJ 1264: 祈雨 Description 在持续了X天的干旱之后,ACM俱乐部决定由LCM去请求雨大师XH祈雨,CMS则准备工具收集雨水,由于ACM俱乐部中有一个逆天的存在,BobLee ...
- go 函数闭包
Go 函数可以是闭包的.闭包是一个函数值,它来自函数体的外部的变量引用. 函数可以对这个引用值进行访问和赋值:换句话说这个函数被“绑定”在这个变量上. 例如,函数 adder 返回一个闭包.每个闭包都 ...