本文对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 的使用的更多相关文章

  1. golang channel的使用以及调度原理

    golang channel的使用以及调度原理 为了并发的goroutines之间的通讯,golang使用了管道channel. 可以通过一个goroutines向channel发送数据,然后从另一个 ...

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

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

  3. golang channel原理

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

  4. golang channel 用法转的

    一.Golang并发基础理论 Golang在并发设计方面参考了C.A.R Hoare的CSP,即Communicating Sequential Processes并发模型理论.但就像John Gra ...

  5. golang channel初次接触

    goroutine之间的同步 goroutine是golang中在语言级别实现的轻量级线程,仅仅利用go就能立刻起一个新线程.多线程会引入线程之间的同步问题,经典的同步问题如生产者-消费者问题,在c, ...

  6. 如何优雅的关闭Golang Channel?

    Channel关闭原则 不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作. 也就是说应该只在[唯一的或者最后唯一剩下]的生产者协程中关闭channel,来通知消费 ...

  7. golang channel几点总结

    golang提倡使用通讯来共享数据,而不是通过共享数据来通讯.channel就是golang这种方式的体现. Channel 在golang中有两种channel:带缓存的和不带缓存. 带缓存的cha ...

  8. golang channel 源码剖析

    channel 在 golang 中是一个非常重要的特性,它为我们提供了一个并发模型.对比锁,通过 chan 在多个 goroutine 之间完成数据交互,可以让代码更简洁.更容易实现.更不容易出错. ...

  9. golang channel本质——共享内存

    channel是golang中很重要的概念,配合goroutine是golang能够方便实现并发编程的关键.channel其实就是传统语言的阻塞消息队列,可以用来做不同goroutine之间的消息传递 ...

  10. Golang channel 用法简介

    channel 是 golang 里相当有趣的一个功能,大部分时候 channel 都是和 goroutine 一起配合使用.本文主要介绍 channel 的一些有趣的用法. 通道(channel), ...

随机推荐

  1. 基于PHP+MYSQL的WEB聊天应用雏形开发实例教程

    更多技术资源:胡旭个人博客 前天,简单利用PHP做了一个简单的WEB聊天应用.没有发到网上,所以就不提供demo了.不过,发布一下源代码(见文尾). 项目说明: 基于PHP+MYSQL的WEB聊天应用 ...

  2. 20165210 Java第四周学习总结

    20165210 Java第四周学习总结 教材学习内容 第五章学习总结 子类与父类: 子类: class 子类名 extends 父类名 { ... } 类的树形结构 子类的继承性: 子类和父类在同一 ...

  3. grafana dashboard的导入导出

    grafana的官方提供了很多社区或者官方设置的漂亮的dashboard,地址如下: 点击打开链接 导入图表大大节省了我们配置监控的时间,非常方便. 以linux host overview为例,首先 ...

  4. vue|html5 form 验证

    html:<form id="scoreForm" @submit="fsub" > <template v-for="(item, ...

  5. SWIFT中获取配置文件路径的方法

    在项目中有时候要添加一些配置文件然后在程序中读取相应的配置信息,以下为本人整理的获取项目配置文件(.plist)路径的方法: 1.获取沙盒路径后再APPEND配置文件 func documentsDi ...

  6. Xcode清理垃圾

    摘抄自https://blog.csdn.net/hu434587115/article/details/54602449 ~/Library/Developer/Xcode/DerivedData/ ...

  7. a demo for how to use QThread

    /******************************************************************* * a demo for how to use QThread ...

  8. OK335xS U-boot 编译问题&无Linux shell 问题

    /************************************************************************** * OK335xS U-boot 编译问题&am ...

  9. 【c++基础】int转string自动补零

    前言 使用to_string函数可以将不同类型的数据转换为string类,请参考here和here.如果string的位数固定,如何进行自动补零呢?请看本文实例! 代码 确定位数,to_string ...

  10. UnicodeDammit

    UnicodeDammit 是BS内置库, 主要用来猜测文档编码. 编码自动检测 功能可以在Beautiful Soup以外使用,检测某段未知编码时,可以使用这个方法: from bs4 import ...