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的值
}
 
[root@localhost 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
 
}
输出结果如下:
[root@localhost 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)
 
}
 
[root@localhost 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")
}
 
}
[root@localhost hello]# go run channel.go
timeout

 

 

 

 

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

 

 

 

 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值