golang channel的使用以及调度原理
golang channel的使用以及调度原理
为了并发的goroutines之间的通讯,golang使用了管道channel。
可以通过一个goroutines向channel发送数据,然后从另一个goroutine接收它。
通常我们会使用make来创建channel ----- make(chan valType, [size])。
写入 c <- data
读取 data := <-c
Golang的channel分为缓冲和非缓冲的两种。主要区别:缓冲chanel是同步的,非缓冲channel是非同步的。
举个例子:
c1 := make(chan int) // 无缓冲: c1 <- 1,当前协程阻塞。
c2 := make(chan int, 1) // 有缓冲: c2 <- 1,当前协程不会阻塞,c2 <- 2,此时1没有被取走,当前协程才阻塞。
备注:
1、给一个nil channel发送数据,造成永远阻塞。
2、从一个nil channel接收数据,造成永远阻塞。
3、给一个已经关闭的channel发送数据,引起panic。
4、从一个已经关闭的channel接收数据,立即返回一个零值(false : bool, 0 : int, 0.0 : float, "" : string, nil : pointer, function, interface, slice, channel, map)。
5、channel关闭多次会引起panic,channel不能close大于1次。
6、可以用两个返回值(valeu, b := <-c)来捕获channel是否关闭,b取值false或true。
缓冲channel的调度:
一、写数据:
1、协程1往channel写数据,buffer为空,读队列为空,直接写入buffer并返回。
2、协程1往channel写数据,buffer为空,读队列非空(协程2阻塞在读队列),协程1将数据交给协程2并唤醒协程2等待调度,协程1返回,调度协程2取得数据并返回。
3、协程1往channel写数据,buffer非空未满,直接写入buffer并返回。
4、协程1往channel写数据,buffer满,加入写队列,阻塞当前协程1,等待有其他协程n从channel读数据。
二、读数据:
1、协程2从channel读数据,buffer非空,写队列非空(协程1阻塞在写队列),唤醒协程1等待调度,协程2从buffer读取数据并返回,调度协程1将数据写入buffer并返回。
2、协程2从channel读数据,buffer非空,写队列空,从buffer读取数据并返回。
3、重复步骤2直至buffer空。
3.1、若写队列为空,加入读队列,阻塞当前协程2,等待有其他协程n往channel写数据。
3.2、若写队列非空(协程1阻塞在写队列),协程2从写队列取出数据并唤醒协程1等待调度,协程2携带数据返回,调度协程1返回。
非缓冲channel的调度:
一、写数据:
1、协程1往channel写数据,读队列为空,加入写队列,阻塞当前协程1,等待有其他协程n从channel读数据。
2、协程1往channel写数据,读队列非空(协程2阻塞在读队列),协程1将数据交给协程2并唤醒协程2等待调度,协程1返回,调度协程2取得数据并返回。
二、读数据:
1、协程2从channel读数据,写队列非空(协程1阻塞在写队列),协程2从写队列取出数据并唤醒协程1等待调度,协程2携带数据返回,调度协程1返回。
2、协程2从channel读数据,写队列为空,加入读队列,阻塞当前协程2,等待有其他协程n往channel写数据。
golang channel的使用以及调度原理的更多相关文章
- golang channel原理
channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...
- Erlang的调度原理(译文)
原文 http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html 免爬墙链接 http://www.diku ...
- 弄懂goroutine调度原理
goroutine简介 golang语言作者Rob Pike说,"Goroutine是一个与其他goroutines 并发运行在同一地址空间的Go函数或方法.一个运行的程序由一个或更多个go ...
- 图解Go协程调度原理,小白都能理解
阅读本文仅需五分钟,golang协程调度原理,小白也能看懂,超实用. 什么是协程 对于进程.线程,都是有内核进行调度,有CPU时间片的概念,进行抢占式调度.协程,又称微线程,纤程.英文名Corouti ...
- python并发编程之进程、线程、协程的调度原理(六)
进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...
- [golang]Golang实现高并发的调度模型---MPG模式
Golang实现高并发的调度模型---MPG模式 传统的并发形式:多线程共享内存,这也是Java.C#或者C++等语言中的多线程开发的常规方法,其实golang语言也支持这种传统模式,另外一种是Go语 ...
- golang channel关闭后,是否可以读取剩余的数据
golang channel关闭后,其中剩余的数据,是可以继续读取的. 请看下面的测试例子. 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channe ...
- go语言之行--golang核武器goroutine调度原理、channel详解
一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...
- [GO语言的并发之道] Goroutine调度原理&Channel详解
并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题:Go语言作为一个出道以来就自带 『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是值得开发者去探究的,而Go ...
随机推荐
- 0基础学python3心得体会 - python3学习笔记 - python3基础
基础预热 print()会依次打印每个字符串,遇到逗号","会输出一个空格,可以打印整数,或者计算 结果 Python提供了一个input(),,可以让用户输入字符串,并存放到一个 ...
- ubuntu下boost编译安装
ubuntu下boost编译安装 boost 安装 1.依赖安装 apt-get install mpi-default-dev libicu-dev python-dev python3-dev l ...
- HDU 5056
题意略. 巧妙的尺取法.我们来枚举每个字符str[i],计算以str[i]为结尾的符合题意的串有多少个.那么我们需要处理出str[i]的左边界j,在[j,i]之间的串均为符合题意的 串,那么str[i ...
- lnmp HTTP ERROR 500
http://www.cnblogs.com/thrillerz/p/4725409.html
- UVA - 11270 轮廓线DP
其实这题还能用状压DP解决,可是时间达到2000ms只能过掉POJ2411.状压DP解法详见状压DP解POJ2411 贴上POJ2411AC代码 : 2000ms 时间复杂度h*w*(2^w)*(2^ ...
- hdu1556 Color the ball 线段树区间染色问题
都是老套路了,如果n=5,要把区间[1,4]染色,可以递归去染区间[1,3]和区间[4,4],如果区间相等就自加,不相等继续递归寻找对应区间. 打印结果时,把所有到达叶节点包含i的区间值相加,就是最后 ...
- 【CF 678F】Lena and Queries
Time Limit: 2000 ms Memory Limit: 512 MB Description 初始有一个空集合 n个操作 有三种操作,如下: 1 a b 表示向集合中插入二元组(a,b ...
- (转载,但不知道谁原创)获取SPRING 代理对象的真实实例,可以反射私有方法,便于测试
/** * 获取 目标对象 * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Ob ...
- 模板语言变量,js变量,js自执行函数之前嵌套调用
1.模板语言变量 前端html页面中展示 {{ nodeIp }} 2.js变量引用模板语言变量 把模板语言变量传递给js,js去执行页面操作(变量的转换,只适用于字符串) var IP = &quo ...
- (转载)windows下mysql忘记密码
Mysql版本:5.1 1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令: net stop mysql 打开第一个cmd窗口,切换到mysql的bin目录 ...