golang 的 buffered channel 及 unbuffered channel
The channel is divided into two categories: unbuffered and buffered.
(1) Unbuffered channel
For unbuffered
channel, the sender will block on the channel until the receiver
receives the data from the channel, whilst the receiver will also block
on the channel until sender sends data into the channel. Check the
following example:
package main import (
"fmt"
"time"
) func main() {
ch := make(chan int) go func(ch chan int) {
fmt.Println("Func goroutine begins sending data")
ch <-
fmt.Println("Func goroutine ends sending data")
}(ch) fmt.Println("Main goroutine sleeps 2 seconds")
time.Sleep(time.Second * ) fmt.Println("Main goroutine begins receiving data")
d := <-ch
fmt.Println("Main goroutine received data:", d) time.Sleep(time.Second)
}
The running result likes this:
Main goroutine sleeps 2 seconds
Func goroutine begins sending data
Main goroutine begins receiving data
Main goroutine received data: 1
Func goroutine ends sending data
After the main goroutine is launched, it will sleep immediately("Main goroutine sleeps 2 seconds" is printed), and this will cause main goroutine relinquishes the CPU to the func goroutine("Func goroutine begins sending data" is printed). But since the main goroutine is sleeping and can't receive data from the channel, so ch <- 1 operation in func goroutine can't complete until d := <- ch in main goroutine is executed(The final 3 logs are printed).
(2) Buffered channel
Compared with unbuffered counterpart, the sender of buffered channel will block when there is no empty slot of the channel, while the receiver will block on the channel when it is empty. Modify the above example:
package main import (
"fmt"
"time"
) func main() {
ch := make(chan int, ) go func(ch chan int) {
for i := ; i <= ; i++ {
ch <- i
fmt.Println("Func goroutine sends data: ", i)
}
close(ch)
}(ch) fmt.Println("Main goroutine sleeps 2 seconds")
time.Sleep(time.Second * ) fmt.Println("Main goroutine begins receiving data")
for d := range ch {
fmt.Println("Main goroutine received data:", d)
}
}
The executing result is as follows:
Main goroutine sleeps 2 seconds
Func goroutine sends data: 1
Func goroutine sends data: 2
Main goroutine begins receiving data
Main goroutine received data: 1
Main goroutine received data: 2
Main goroutine received data: 3
Func goroutine sends data: 3
Func goroutine sends data: 4
Func goroutine sends data: 5
Main goroutine received data: 4
Main goroutine received data: 5
In this sample, since the channel has 2 slots, so the func goroutine will not block until it sends the third element.
P.S., "make(chan int, 0)" is equal to "make(chan int)", and it will create an unbuffered int channel too.
golang 的 buffered channel 及 unbuffered channel的更多相关文章
- [GO]无缓冲通道(unbuffered channel)
无缓冲通道(unbuffered channel)是指在接收前没有能力保存任何值的通道,在之前的例子中使用的都是无缓冲通道,需要注意的是,对于无缓冲通道而言,不管是往通道里写数据还是从通道里读数据,都 ...
- Golang的goroutine协程和channel通道
一:简介 因为并发程序要考虑很多的细节,以保证对共享变量的正确访问,使得并发编程在很多情况下变得很复杂.但是Go语言在开发并发时,是比较简洁的.它通过channel来传递数据.数据竞争这个问题在gol ...
- go语言之行--golang核武器goroutine调度原理、channel详解
一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...
- 实时事件统计项目:优化flume:用file channel代替mem channel
背景:利用kafka+flume+morphline+solr做实时统计. solr从12月23号开始一直没有数据.查看日志发现,因为有一个同事加了一条格式错误的埋点数据,导致大量error. 据推断 ...
- netty源码解解析(4.0)-12 Channel NIO实现:channel初始化
创建一个channel实例,并把它register到eventLoopGroup中之后,这个channel然后处于inactive状态,仍然是不可用的.只有在bind或connect方法调用成功之后才 ...
- Netty Tutorial Part 1.5: On Channel Handlers and Channel Options [z]
Intro: After some feedback on Part 1, and being prompted by some stackoverflow questions, I want to ...
- Fibre Channel和Fiber Channel
Fibre Channel也就是"网状通道"的意思,简称FC. 由于Fiber和Fibre只有一字之差,所以产生了很多流传的误解. FC只代表Fibre Channel,而不是 ...
- golang channel 用法转的
一.Golang并发基础理论 Golang在并发设计方面参考了C.A.R Hoare的CSP,即Communicating Sequential Processes并发模型理论.但就像John Gra ...
- 深入学习golang(2)—channel
Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网 ...
随机推荐
- 一、K3 Cloud 实施指导《K3 Cloud实施手册》
1.在BOS的单据体取不到序号字段 举例:单据体标识是FValueGrid,序号标识是FSeq,取到的序号标识要写成FValueGrid_FSeq才能识别到 2.k3 Cloud目前不支持在表头字段调 ...
- openresty的安装和使用
1,简介 OpenResty(又称:ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台,是一个强大的 Web 应用服务器,在性能方面,OpenResty可以 快速构造出足以 ...
- excel 导入mysql
1. excel 导出csv格式,很简单导出即可 2. 使用命令行,进入mysql之后,使用命令行 tips: 删除第一行的属性名,csv后面若有空数据也可以删除,当然你不删除也没有关系,可以在mys ...
- 在Android源码中查找Java代码中native函数对应的C++实现
Android源码中很多关键代码都是C++实现的,java通过jni来调用,经常会看到java中这样的代码: static native Thread currentThread(); 如何根据方法名 ...
- Scala断言
断言:提供了一组断言函数以用作在代码中记录和动态检查不变量的方式. import scala.Predef._ def addNaturals(nats: List[Int]): Int = { // ...
- xml和json格式输出
<?php class Response{ const JSON ='json'; /* * 按综合方式输出通信数据 * @param integer $ ...
- 关于启动VS2012时,提示Web4.0尚未在网络服务器上注册的解决办法!
VS2012在没有Web服务器上注册的问题,网上有很多博客. 开始我就是遇到这个问题,在网上试了几个办法,确实都还可以.但是相比之下有的需要设置DOS,进行安装.exe. 这种方法其实相比直接安装补丁 ...
- MSI/MSI-X Capability结构 (转)
http://blog.sina.com.cn/s/blog_6472c4cc0102dskj.html
- 洛谷P1098 字符串的展开【字符串】【模拟】
题目描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h”或者“4-8”的字串,我们就把它当作一种简写,输出时,用连续递增的字母或数 ...
- Java NIO 读取文件、写入文件、读取写入混合
前言 Java NIO(new/inputstream outputstream)使用通道.缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position).限制(limi ...