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的使用以及调度原理的更多相关文章

  1. golang channel原理

    channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...

  2. Erlang的调度原理(译文)

    原文 http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html 免爬墙链接 http://www.diku ...

  3. 弄懂goroutine调度原理

    goroutine简介 golang语言作者Rob Pike说,"Goroutine是一个与其他goroutines 并发运行在同一地址空间的Go函数或方法.一个运行的程序由一个或更多个go ...

  4. 图解Go协程调度原理,小白都能理解

    阅读本文仅需五分钟,golang协程调度原理,小白也能看懂,超实用. 什么是协程 对于进程.线程,都是有内核进行调度,有CPU时间片的概念,进行抢占式调度.协程,又称微线程,纤程.英文名Corouti ...

  5. python并发编程之进程、线程、协程的调度原理(六)

    进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...

  6. [golang]Golang实现高并发的调度模型---MPG模式

    Golang实现高并发的调度模型---MPG模式 传统的并发形式:多线程共享内存,这也是Java.C#或者C++等语言中的多线程开发的常规方法,其实golang语言也支持这种传统模式,另外一种是Go语 ...

  7. golang channel关闭后,是否可以读取剩余的数据

    golang channel关闭后,其中剩余的数据,是可以继续读取的. 请看下面的测试例子. 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channe ...

  8. go语言之行--golang核武器goroutine调度原理、channel详解

    一.goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式非常的简单,只需使用go关键字 ...

  9. [GO语言的并发之道] Goroutine调度原理&Channel详解

    并发(并行),一直以来都是一个编程语言里的核心主题之一,也是被开发者关注最多的话题:Go语言作为一个出道以来就自带 『高并发』光环的富二代编程语言,它的并发(并行)编程肯定是值得开发者去探究的,而Go ...

随机推荐

  1. 图论算法-Tarjan模板 【缩点;割顶;双连通分量】

    图论算法-Tarjan模板 [缩点:割顶:双连通分量] 为小伙伴们总结的Tarjan三大算法 Tarjan缩点(求强连通分量) int n; int low[100010],dfn[100010]; ...

  2. shiro笔记-AuthenticatingRealm和AuthorizingRealm关系

    AuthenticatingRealm-------->用于认证方法的Realm AuthorizingRealm--------->用于授权和认证的realm一般使用这个 Authori ...

  3. MysqL读写分离的实现-Mysql proxy中间件的使用

    为什么要架设读写分离,这里不做多余的说明,想了解具体原理,请百度或者参考其他帖子.在这里只做大概的配置说明,测试中使用三台服务器 192.168.136.142   主服务器 192.168.136. ...

  4. MySQL取得某一范围随机数

    ①直接取值 若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)). 例如, 若要在7 到 12 的范围(包括7和12) ...

  5. hive上mysql元数据库配置

    hive调试信息显示模式: ./hive -hiveconf hive.root.logger=DEBUG,console 非常有用. 默认情况下,Hive元数据保存在内嵌的 Derby 数据库中,只 ...

  6. KVM虚拟化网络优化技术总结

    https://www.intel.com/content/dam/www/public/us/en/documents/technology-briefs/sr-iov-nfv-tech-brief ...

  7. word自动备份,word误删内容恢复

    有个问题时长困扰着我,就是一次不小心把word里面的一部分内容误删了之后,又手残点击ctrl+s给保存了,要是立即ctrl+z还能撤销,可要是关闭了word才想起来撤销就来不及啦,现在终于找到解决的办 ...

  8. 2_Add Two Numbers --LeetCode

    原题如下: 思路:在一个while中遍历两个链表,直到最长的链表为空,或者没有进位.每一步获取两个链表对应的结点的值a,b,然后相加a+b.如果上一步又进位,那就加a+b+1,若由于进位加1后还产生进 ...

  9. golang调试工具Delve

    Devle是一个非常棒的golang 调试工具,支持多种调试方式,直接运行调试,或者attach到一个正在运行中的golang程序,进行调试. 线上golang服务出现问题时,Devle是必不少的在线 ...

  10. Android项目中的换肤总结

    纵观现在各种Android app,其换肤需求可以归为 白天/黑夜主题切换(或者别的名字,通常2套),如同花顺/自选股/天天动听等,UI表现为一个switcher. 多种主题切换,通常为会员特权,如Q ...