go channel例子

channel初步认识:

package main

import "fmt"
import "time"

func main() {
c := make(chan int) //初始化一个管道
defer close(c) //在main函数执行完毕之后执行。
go func() { //会开启一个协程,并往管道c写入数据
time.Sleep(2 * time.Second)
fmt.Println("all ready")
c <- 3 + 4
}()
i := <-c // 将管道c的内容输出赋值到i,在c还没有内容的时候,会一直阻塞在这里。
fmt.Println(i) //打印i的值
}

[[email protected] hello]# go run channel.go
all ready
7

如注释所示,在管道还没有内容输入之前i := <-c这个语句一直被阻塞着。

往一个已经被close的channel中继续发送数据会导致run-time panic。

如下:

package main

import "fmt"
import "time"

func main() {
c := make(chan int) //初始化一个管道
go func() { //会开启一个协程,并往管道c写入数据
time.Sleep(2 * time.Second)
fmt.Println("all ready")
c <- 3 + 4
close(c)
}()
i := <-c // 将管道c的内容输出赋值到i,在c还没有内容的时候,会一直阻塞在这里。
fmt.Println(i) //打印i的值
c <- 8 //由于c已经在协程里面被关闭,这句将引起run-time panic

}
输出结果如下:
[[email protected] hello]# go run channel.go
all ready
7
panic: send on closed channel

goroutine 1 [running]:
main.main()
/mnt/hgfs/share/eclipse/testgo/src/hello/channel.go:16 +0x125
exit status 2

可以使用一个额外的返回参数来检查channel是否关闭。

x, ok := <-ch

如果OK 是false,表明接收的x是产生的零值,这个channel被关闭了或者为空。

另一种是可以用for range处理这种管道是否有数据的情况,在管道被关闭时for range会退出。

func main() {
go func() {
time.Sleep(1 * time.Hour)
}()
c := make(chan int)
go func() {
for i := 0; i < 10; i = i + 1 {
c <- i
}
close(c) //如果将此句注释掉,那么下面的for range在打印完管道的内容后会一直阻塞。
}()
for i := range c {
fmt.Println(i)
}
fmt.Println("Finished")
}

select 类似于switch,里面的case可以是recieve或send或default语句。

如果同时有多个case满足条件,那么Go会伪随机的选择一个case处理,如果没有case需要处理,则会选择default去处理。如果没有default case,则select语句会阻塞,直到某个case需要处理。

package main

import (
"fmt"
)

func fab(c, quit chan int) {
x, y := 0, 1

for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
return
}
}

}

func main() {
c := make(chan int)
quit := make(chan int)

go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()

fab(c, quit)

}

[[email protected] hello]# go run channel.go
0
1
1
2
3
5
8
13
21
34

超时处理:

package main

import (
"fmt"
"time"
)

func main() {

c := make(chan string)

go func() {
time.Sleep(30 * time.Second)
c <- "Hello World"
}()

select {
case res := <-c:
fmt.Println(res)
case <-time.After(2 * time.Second):
fmt.Println("timeout")
}

}
[[email protected] hello]# go run channel.go
timeout

参考来源:http://colobu.com/2016/04/14/Golang-Channels/

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

时间: 2024-11-04 14:02:11

go channel例子的相关文章

如何使用 channel

如何使用 Channel 例子来自于Concurrency is not parallelism Google Search: A fake framework v1.0 var ( Web = fakeSearch("web") Image = fakeSearch("image") Video = fakeSearch("video") ) type Search func(query string) Result func fakeSear

Redis(2)-----初识Redis-----基础redis命令

hash类型(散列map)HMSET mymap1 name "qingruihappy" description "suning" age "20" sex "man" sex "man" sex "man" sex "man"HMSET mymap2 name "qingruihappy" description "suning&qu

Flume-ng源码解析之Channel组件

如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后是Source,在开始看组件源码之前我们先来看一下两个重要的接口,一个是LifecycleAware ,另一个是NamedComponent 1.1 LifecycleAware @[email protected] interface LifecycleAware {  public void s

TODO:Go语言goroutine和channel使用

goroutine是Go语言中的轻量级线程实现,由Go语言运行时(runtime)管理.使用的时候在函数前面加"go"这个单词作为关键词,也是与普通函数的区别了.在函数前面加go关键字就可以创建一个新的goroutine进行并发执行. go hello() channel是Go语言提供的goroutine间的通信方式,我们可以使用channel在两个或多个goroutine之家传递消息.channel使用的关键字是用"chan",声明一个传递类型为int的chann

《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果

本文完全转载:http://www.cnblogs.com/Imageshop/p/3281703.html,再次仅当学习交流使用.. <Single Image Haze Removal Using Dark Channel Prior>一文中图像去雾算法的原理.实现.效果(速度可实时) 本文算法合作联系QQ: 33184777, 非诚勿扰 邮件地址:   [email protected] 最新的效果见 :http://video.sina.com.cn/v/b/124538950-125

Netty Channel 接口名词理解

1.Channel channel 是负责数据读,写的对象,有点类似于老的io里面的stream.它和stream的区别,channel是双向的,既可以write 也可以read,而stream要分outstream和inputstream.而且在NIO中用户不应该直接从channel中读写数据,而是应该通过buffer,通过buffer再将数据读写到channel中. 一个channel 可以提供给用户下面几个信息 (1)channel的当前状态,比如open 还是closed (2)Chan

如何创建一个Hyperledger Fabric channel

创建channel的步骤: 执行configtxgen tool来生成genesis block: 执行configtxgen tool来生成初始二进制配置定义: 通过以下两种方式获取sign-able channel定义:1)使用初始二进制channel配置定义-使用fabric-client SDK从初始二进制配置定义中解析出sign-able channel定义:2)建立一个定制的定义-使用configtxlator将初始二进制channel配置定义转换成可读文本-编辑可读文本-使用con

根据百度的语音识别例子,展示C如何使用cJSON

前面一篇文章展示了根据百度语音识别例子如何用C调用C++的方法,这篇文章也是基于百度语音识别,展示如何使用cJSON,cJSON是一个用C写的JSON解析器,非常好用,可以用它来生成一个JSON,也可以用来解析JSON的值. 在我写的通过skey获取token的代码中 char *token = (char *)malloc(MAX_BUFFER_SIZE); char host[MAX_BUFFER_SIZE]; snprintf(host, sizeof(host), "https://op

java的nio之:java的nio系列教程之channel的概念

一:java的nio的channel Java NIO的通道类似流,但又有些不同: ==>既可以从通道中读取数据,又可以写数据到通道.但流的读写通常是单向的. ==>通道可以异步地读写. ==>通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入. 正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道.如下图所示: 二:java的nio的channel的实现 这些是Java NIO中最重要的通道的实现: ==>FileChannel  : ==>