golang基础-chan的select操作、定时器操作、超时控制、goroutine中使用recover

chan的只读和只写

a.只读chan的声明
Var 变量的名字 <-chan int
Var readChan <- chan int

b. 只写chan的声明
Var 变量的名字 chan<- int
Var writeChan chan<- int

chan的select操作

格式如下

Select {
     case u := <- ch1:
     case e := <- ch2:
     default: }

看实例代码

package main

import "fmt"
import "time"

func main() {
    var ch chan @H_403_49@int
    ch = make(chan @H_403_49@int ,10)
    ch2:= make(chan @H_403_49@int ,10)

    go func(){
        var i @H_403_49@int
        for {
            ch <- i
            time.Sleep(time.Second)
            ch2 <- i * i
            time.Sleep(time.Second)
            i ++
        }
    }()

    for {
        select{
        case v:= <-ch:
            fmt.Println(v)
        case v:= <-ch2:
            fmt.Println(v)
        default:
            fmt.Println("get data timeout")
            time.Sleep(time.Second)
        }
    }
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
0
get data timeout
0
get data timeout
1
get data timeout
1
get data timeout
2
get data timeout
4
get data timeout
3
get data timeout
9
get data timeout
4
get data timeout
16
get data timeout
5
get data timeout
exit status 2
PS E:\golang\go_pro\src\safly>

chan的定时器

package main

import "fmt"
import "time"

/* type Ticker struct { C <-chan Time r runtimeTimer } */

func main() {
    t := time.NewTicker(time.Second)
    for v := range t.C {
        fmt.Println("hello,",v)
    }

}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
hello,2017-11-11 18:50:38.165007 +0800 CST
hello,2017-11-11 18:50:39.1652525 +0800 CST
hello,2017-11-11 18:50:40.165327 +0800 CST
hello,2017-11-11 18:50:41.1650873 +0800 CST
exit status 2
PS E:\golang\go_pro\src\safly>

一次定时器

package main

import "fmt"
import "time"


/* func After(d Duration) <-chan Time { return NewTimer(d).C } */
func main() {
    select {
    case <- time.After(time.Second):
         fmt.Println("after")
    }
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
after
PS E:\golang\go_pro\src\safly>

超时控制

package main

import "fmt"
import "time"


func queryDb(ch chan @H_403_49@int) {

        // time.Sleep(time.Second)
        ch <- 100
}


func main() {
    ch := make(chan @H_403_49@int)
    go queryDb(ch)
    t := time.NewTicker(time.Second)

    select {
    case v := <-ch:
        fmt.Println("result",v)
    case <-t.C:
        fmt.Println("timeout")
    }

}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
result 100
PS E:\golang\go_pro\src\safly>

以上代码是没有超时的,我们将上面代码中 // time.Sleep(time.Second)注释去掉
就会输出如下的结果

PS E:\golang\go_pro\src\safly> go run demo.go
timeout
PS E:\golang\go_pro\src\safly>

goroutine中使用recover

应用场景,如果某个goroutine panic了,而且这个goroutine里面没有
捕获(recover),那么整个进程就会挂掉。所以,好的习惯是每当go产
生一个goroutine,就需要写下recover

package main

import (
    "fmt"
    // "runtime"
    "time"
)

func test() {

    defer func() {
        if err := recover(); err != nil {
            fmt.Println("panic:",err)
        }
    }()

    var m map[@H_403_49@string]@H_403_49@int
    m["stu"] = 100

}

func calc() {
    for {
        fmt.Println("i'm calc")
        time.Sleep(time.Second)
    }
}

func main() {

    go test()
    for i := 0; i < 2; i++ {
        go calc()
    }

    time.Sleep(time.Second * 10000)
}

输出如下:

PS E:\golang\go_pro\src\safly> go run demo.go
i'm calc
panic: assignment to entry in nil map
i'm calc
i'm calc
i'm calc
i'm calc
i'm calc
i'm calc
i'm calc
exit status 2
PS E:\golang\go_pro\src\safly>

相关文章

程序目录结构 简单实现,用户登录后返回一个jwt的token,下次请求带上token请求用户信息接口并返回信息...
本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简...
简介 默克尔树(MerkleTree)是一种典型的二叉树结构,其主要特点为: 最下面的叶节点包含存储数据或其...
接下来学习并发编程, 并发编程是go语言最有特色的地方, go对并发编程是原生支持. goroutine是go中最近本...
先普及一下, 什么是广度优先搜索 广度优先搜索类似于树的层次遍历。从图中的某一顶点出发,遍历每一个顶...
第一天: 接口的定义和实现 第二天: 一. go语言是面向接口编程. 在学习继承的时候说过, go语言只有封装,...