博客网址:www.shicoder.top
微信:kj11011029
欢迎加群聊天 :452380935
这个系列主要是对go
的一些语法和应用进行代码讲解
channel遍历
func main() {
channels := make([]chan int, 10)
for i := 0; i < 10; i++ {
go func(ch chan int) {
time.Sleep(time.Second)
ch <- 1
}(channels[i])
}
for ch := range channels {
fmt.Println("Routine ", ch, " quit!")
}
fmt.Println("结束")
}
func main() {
ch := make(chan int, 10)
for i := 0; i < 10; i++ {
go func() {
ch <- i
}()
}
for range ch {
<-ch
}
fmt.Println(1111)
}
上面两个代码的却别:
- 第一个会正常输出
- 第二个会阻塞
因为for range channel
会一直读取channel
,若没有close channel
,还会继续遍历,则会出现死锁,而第一个中因为是for range channels
,此时的channels
是一个切片,遍历次数知道,所以不会出现死锁。
因此注意range channel
时候,一定要close channel
非阻塞channel
func main() {
var c1 chan string = make(chan string)
func() {
time.Sleep(time.Second)
c1 <- "1"
}()
fmt.Println("c1 is", <-c1)
}
因为是无缓冲管道,有一个特点必须读写同时操作才会有效果,如果只进行读或者只进行写那么会被阻塞,因此我们只能使用go协程来杜绝阻塞
func main() {
var c1 chan string = make(chan string)
go func() {
time.Sleep(time.Second)
c1 <- "1"
}()
fmt.Println("c1 is", <-c1)
}
或者使用有缓冲管道
func main() {
var c1 chan string = make(chan string, 1)
func() {
time.Sleep(time.Second)
c1 <- "1"
}()
fmt.Println("c1 is", <-c1)
}
或者使用select
的default
来进行默认处理
func main() {
var c1 chan string = make(chan string)
var c2 chan string = make(chan string)
time.Sleep(time.Second)
select {
case c := <-c1:
fmt.Println(c)
case c := <-c2:
fmt.Println(c)
default:
fmt.Println("After one second!")
}
}
// 或者使用time超时
func main() {
var c1 chan string = make(chan string)
select {
case c := <-c1:
fmt.Println(c)
case <-time.After(time.Second):
fmt.Println("After one second!")
}
}
评论 (0)