zoukankan      html  css  js  c++  java
  • 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/

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

  • 相关阅读:
    来电科技:基于Flink+Hologres的实时数仓演进之路
    实时计算 Flink 版总体介绍
    阿里云江岑:云原生在边缘形态下的升华
    xshell帮助
    版本控制工具之git
    批量修改ubuntu用户sudo免密码
    matplotlib按钮控制图像显示
    为ssh主机设置别名
    VScode正则表达式批量删除字符串
    SQL Server 操作XML数据
  • 原文地址:https://www.cnblogs.com/zejin2008/p/7169445.html
Copyright © 2011-2022 走看看