美文网首页
解答一道golang面试题

解答一道golang面试题

作者: 十年磨一剑1111 | 来源:发表于2022-05-13 17:06 被阅读0次
  1. for select时,如果通道已经关闭会怎么样?如果只有⼀个case呢?
    先说下猜想:通道虽然关闭了,但是还是可以从里面取出数据的,所以并没有什么影响,如果只有一个case,而这个case 如果还没有准备好会一直阻塞,下面来举个例子来验证下我们的猜想:
package main
import (
    "fmt"
    "time"
)
func main() {
     ch := make(chan int)
     go func(){
           for {
                select {
                     case a:= <- ch
                          fmt.Println("a:",a)
                }
           }
     }()
     ch <- 1
     close(ch)
     time.Sleep(time.Second)
     fmt.Println("main结束")
}

这段代码for select 会持续打印1秒钟,然后程序退出,下面看下执行结果:


4.png

所以从执行结果来看即使channel 关闭了也不会太影响,不过我们可以在读取数据的时间判断channel 是否关闭,如果已经关闭退出循环即可,下面修改下上面的代码:

package main
import (
    "fmt"
    "time"
)
func main() {
     ch := make(chan int)
     go func(){
           for {
                select {
                     case a,ok := <- ch
                          if !ok {
                             return
                          }
                          fmt.Println("a:",a)
                }
           }
     }()
     ch <- 1
     close(ch)
     time.Sleep(time.Second)
     fmt.Println("main结束")
}

另外,如果select case 只有一个case,如果io事件一直没有准备好,那么会导致程序卡死,这个时候我们可以设置一个超时时间:

package main
import (
    "fmt"
    "time"
)
func main() {
     ch := make(chan int)
     go func(){
           for {
                select {
                     case a,ok := <- ch
                          if !ok {
                             return
                          }
                          fmt.Println("a:",a)
                        case <-time.After(5 * time.Second):
                fmt.Println("超时")
                return
            }
                }
           }
     }()
     ch <- 1
     close(ch)
     time.Sleep(time.Second)
     fmt.Println("main结束")
}

解答完毕!

相关文章

网友评论

      本文标题:解答一道golang面试题

      本文链接:https://www.haomeiwen.com/subject/anpocltx.html