作者:xuyuankeji_954 | 来源:互联网 | 2023-08-04 10:52
-
-
-
- chan的只读和只写
- chan的select操作
- chan的定时器
- 一次定时器
- 超时控制
- 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 :&#61; <- ch1:
case e :&#61; <- ch2:
default: }
看实例代码&#xff1a;
package main
import "fmt"
import "time"
func main() {
var ch chan int
ch &#61; make(chan int ,10)
ch2:&#61; make(chan int ,10)
go func(){
var i int
for {
ch <- i
time.Sleep(time.Second)
ch2 <- i * i
time.Sleep(time.Second)
i &#43;&#43;
}
}()
for {
select{
case v:&#61; <-ch:
fmt.Println(v)
case v:&#61; <-ch2:
fmt.Println(v)
default:
fmt.Println("get data timeout")
time.Sleep(time.Second)
}
}
}
输出如下&#xff1a;
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 :&#61; time.NewTicker(time.Second)
for v :&#61; range t.C {
fmt.Println("hello, ", v)
}
}
输出如下&#xff1a;
PS E:\golang\go_pro\src\safly> go run demo.go
hello, 2017-11-11 18:50:38.165007 &#43;0800 CST
hello, 2017-11-11 18:50:39.1652525 &#43;0800 CST
hello, 2017-11-11 18:50:40.165327 &#43;0800 CST
hello, 2017-11-11 18:50:41.1650873 &#43;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")
}
}
输出如下&#xff1a;
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 int) {
// time.Sleep(time.Second)
ch <- 100
}
func main() {
ch :&#61; make(chan int)
go queryDb(ch)
t :&#61; time.NewTicker(time.Second)
select {
case v :&#61; <-ch:
fmt.Println("result", v)
case <-t.C:
fmt.Println("timeout")
}
}
输出如下&#xff1a;
PS E:\golang\go_pro\src\safly> go run demo.go
result 100
PS E:\golang\go_pro\src\safly>
以上代码是没有超时的&#xff0c;我们将上面代码中 // 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
应用场景&#xff0c;如果某个goroutine panic了&#xff0c;而且这个goroutine里面没有
捕获(recover)&#xff0c;那么整个进程就会挂掉。所以&#xff0c;好的习惯是每当go产
生一个goroutine&#xff0c;就需要写下recover
package main
import (
"fmt"
// "runtime"
"time"
)
func test() {
defer func() {
if err :&#61; recover(); err !&#61; nil {
fmt.Println("panic:", err)
}
}()
var m map[string]int
m["stu"] &#61; 100
}
func calc() {
for {
fmt.Println("i&#39;m calc")
time.Sleep(time.Second)
}
}
func main() {
go test()
for i :&#61; 0; i <2; i&#43;&#43; {
go calc()
}
time.Sleep(time.Second * 10000)
}
输出如下&#xff1a;
PS E:\golang\go_pro\src\safly> go run demo.go
i&#39;m calc
panic: assignment to entry in nil map
i&#39;m calc
i&#39;m calc
i&#39;m calc
i&#39;m calc
i&#39;m calc
i&#39;m calc
i&#39;m calc
exit status 2
PS E:\golang\go_pro\src\safly>