golang channel 的使用
本文对channel使用中的几个疑惑,以例子的形式加以说明。
普通channel
缺省情况下,发送和接收会一直阻塞着,直到另一方准备好.
例如:
package main
import (
        "fmt"
        "time"
)
var ch1 chan bool
func main(){
        ch1 = make(chan bool)
        go reader()
        go writer()
        select {
        }
}
func writer() {
        time.Sleep(10*time.Second)
        for {
                ch1 <- true
                fmt.Println("write one ...")
        }
}
func reader() {
        for {
                select {
                case <-ch1:
                        fmt.Println("read one ....")
                }
                time.Sleep(2*time.Second)
        }
}
output:
$ ./chan1.exe
write one ...
read one ....
read one ....
write one ...
read one ....
write one ...
read one ....
write one ...
从执行结果看,reader卡住,直到writer sleep后就位,才继续执行。反之,让reader先睡眠,writer也会卡住,直到reader sleep后就位。
带buffer的channel
带buffer的channel可以减少阻塞,对一些需要只保持有限个执行过程的情景很有用。
例1:
// reader wait, until writer begin to write.
package main
import (
        "fmt"
        "time"
)
var ch1 chan bool
func main(){
        ch1 = make(chan bool, 1)
        go reader()
        go writer()
        select {
        }
}
func writer() {
        time.Sleep(10*time.Second)
        for {
                ch1 <- true
                fmt.Println("write one ...")
        }
}
func reader() {
        for {
                select {
                case <-ch1:
                        fmt.Println("read one ....")
                }
                time.Sleep(2*time.Second)
        }
}
这种情景中,先让writer睡眠,reader此时卡住,直到writer就位,也就是说,带buffer,如果没有数据写入,reader也是卡住的。
例2:
// writer write one, then wait
package main
import (
        "fmt"
        "time"
)
var ch1 chan bool
func main(){
        ch1 = make(chan bool, 1)
        go reader()
        go writer()
        select {
        }
}
func writer() {
        for {
                ch1 <- true
                fmt.Println("write one ...")
        }
}
func reader() {
        time.Sleep(10*time.Second)
        for {
                select {
                case <-ch1:
                        fmt.Println("read one ....")
                }
                time.Sleep(2*time.Second)
        }
}
如果先让reader睡眠,writer直接向channel写,可以看到writer可以写入一个数据,然后卡住,直到reader就位,才可以继续写。
也就是说,带一个buffer的channel,可以在reader就位前首先写入一个数据。
参考
http://colobu.com/2016/04/14/Golang-Channels/
golang channel 的使用的更多相关文章
- golang channel的使用以及调度原理
		golang channel的使用以及调度原理 为了并发的goroutines之间的通讯,golang使用了管道channel. 可以通过一个goroutines向channel发送数据,然后从另一个 ... 
- golang  channel关闭后,是否可以读取剩余的数据
		golang channel关闭后,其中剩余的数据,是可以继续读取的. 请看下面的测试例子. 创建一个带有缓冲的channel,向channel中发送数据,然后关闭channel,最后,从channe ... 
- golang channel原理
		channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ... 
- golang channel 用法转的
		一.Golang并发基础理论 Golang在并发设计方面参考了C.A.R Hoare的CSP,即Communicating Sequential Processes并发模型理论.但就像John Gra ... 
- golang channel初次接触
		goroutine之间的同步 goroutine是golang中在语言级别实现的轻量级线程,仅仅利用go就能立刻起一个新线程.多线程会引入线程之间的同步问题,经典的同步问题如生产者-消费者问题,在c, ... 
- 如何优雅的关闭Golang Channel?
		Channel关闭原则 不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作. 也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费 ... 
- golang channel几点总结
		golang提倡使用通讯来共享数据,而不是通过共享数据来通讯.channel就是golang这种方式的体现. Channel 在golang中有两种channel:带缓存的和不带缓存. 带缓存的cha ... 
- golang channel 源码剖析
		channel 在 golang 中是一个非常重要的特性,它为我们提供了一个并发模型.对比锁,通过 chan 在多个 goroutine 之间完成数据交互,可以让代码更简洁.更容易实现.更不容易出错. ... 
- golang channel本质——共享内存
		channel是golang中很重要的概念,配合goroutine是golang能够方便实现并发编程的关键.channel其实就是传统语言的阻塞消息队列,可以用来做不同goroutine之间的消息传递 ... 
- Golang channel 用法简介
		channel 是 golang 里相当有趣的一个功能,大部分时候 channel 都是和 goroutine 一起配合使用.本文主要介绍 channel 的一些有趣的用法. 通道(channel), ... 
随机推荐
- C++技能重拾
			0.虽然静态成员函数不存在this指针,但还是不能在一个class里声明同名同参的虚函数和静态成员函数. 1.vftable里一个虚函数表是一个指针 2.delete本质,调用析构函数同时释放内存Ob ... 
- 流媒体传输协议详解之---RTSP认证
			from:http://blog.csdn.net/machh/article/details/52121648 Rtsp认证主要分为两种: 基本认证(basic authentication)和 ... 
- PHP:第四章——数组中的排序函数
			<pre> <?php header("Content-Type:text/html;charset=utf-8"); //1) /*sort - 对数组进行升序 ... 
- 什么是 dynaTrace Ajax
			随着 jQuery.Dojo.YUI 等框架的兴起让构建 Web2.0 应用更加容易,但随之带来的定位等应用问题也越来越难,尤其是与性能相关的.dynaTrace Ajax Edition 是一个强大 ... 
- Objective-C  类别(category)和扩展(Extension)
			1.类别(category) 使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以 ... 
- java读取大容量excel之一
			最近在用poi读取大容量excel,发现只要是excel文件大于2M左右,便会出现OOM(out of memory),经过查询得知,原来poi读取excel的原理是如下: org.apache.po ... 
- 26个你不知道的Python技巧
			Python是目前世界上最流行的编程语言之一.因为: 1.它容易学习 2.它用途超广 3.它有非常多的开源支持(大量的模块和库) 不好意思,优达菌又啰嗦了. 本文作者 Peter Gleeson 是一 ... 
- HDU 3488
			http://acm.hdu.edu.cn/showproblem.php?pid=3488 原来写过的一道题,今天重新看费用流又做了一遍 题意:给一个图,求环的并(权值和最小) 思路:每个点只能走一 ... 
- tensorflow中的参数初始化方法
			1. 初始化为常量 tf中使用tf.constant_initializer(value)类生成一个初始值为常量value的tensor对象. constant_initializer类的构造函数定义 ... 
- 如何安装Magento插件
			Magento有着非常多的插件,其实就是模块,那么怎么安装需要的插件呢? 具体方法如下,以安装DeveloperToolbar这个开发插件为例讲解: 1.首先到Magento的官方网站查找到相应的插件 ... 
