golang面试官:for select时,如果通道已经关闭会怎么样?如果select中只有一个case呢?

简介: golang面试官:for select时,如果通道已经关闭会怎么样?如果select中只有一个case呢?

问题

for循环select时,如果通道已经关闭会怎么样?如果select中的case只有一个,又会怎么样?

怎么答

  • for循环select时,如果其中一个case通道已经关闭,则每次都会执行到这个case。
  • 如果select里边只有一个case,而这个case被关闭了,则会出现死循环。

解释

1.for循环里被关闭的通道

  • c通道是一个缓冲为0的通道,在main开始时,启动一个协程对c通道写入10,然后就关闭掉这个通道。
  • main中通过 x, ok := <-c 接受通道c里的值,从输出结果里看出,确实从通道里读出了之前塞入通道的10,但是在通道关闭后,这个通道一直能读出内容。

2.怎么样才能不读关闭后通道

  • x, ok := <-c 返回的值里第一个x是通道内的值,ok是指通道是否关闭,当通道被关闭后,ok则返回false,因此可以根据这个进行操作。读一个已经关闭的通道为什么会出现false,可以看我之前的 对已经关闭的的chan进行读写,会怎么样?为什么?
  • 当返回的okfalse时,执行c = nil 将通道置为nil,相当于读一个未初始化的通道,则会一直阻塞。至于为什么读一个未初始化的通道会出现阻塞,可以看我的另一篇 对未初始化的的chan进行读写,会怎么样?为什么?select中如果任意某个通道有值可读时,它就会被执行,其他被忽略。则select会跳过这个阻塞case,可以解决不断读已关闭通道的问题。

3.如果select里只有一个已经关闭的case,会怎么样?

  • 可以看出只有一个case的情况下,则会死循环
  • 那如果像上面一个case那样,把通道置为nil就能解决问题了吗?

4.select里只有一个已经关闭的case,置为nil,会怎么样?

  • 第一次读取case能读到通道里的10
  • 第二次读取case能读到通道已经关闭的信息。此时将通道置为nil
  • 第三次读取case时main协程会被阻塞,此时整个进程没有其他活动的协程了,进程deadlock

总结

  • select中如果任意某个通道有值可读时,它就会被执行,其他被忽略。
  • 如果没有default字句,select将有可能阻塞,直到某个通道有值可以运行,所以select里最好有一个default,否则将有一直阻塞的风险。
目录
相关文章
|
6月前
|
Go
golang力扣leetcode 面试题04.06.后继者
golang力扣leetcode 面试题04.06.后继者
46 0
|
6月前
|
Go 调度
浅谈Golang通道channel
浅谈Golang通道channel
71 0
|
6月前
|
程序员 Go
Golang深入浅出之-Select语句在Go并发编程中的应用
【4月更文挑战第23天】Go语言中的`select`语句是并发编程的关键,用于协调多个通道的读写。它会阻塞直到某个通道操作可行,执行对应的代码块。常见问题包括忘记初始化通道、死锁和忽视`default`分支。要解决这些问题,需确保通道初始化、避免死锁并添加`default`分支以处理无数据可用的情况。理解并妥善处理这些问题能帮助编写更高效、健壮的并发程序。结合使用`context.Context`和定时器等工具,可提升`select`的灵活性和可控性。
103 2
|
3月前
|
监控 Go
|
3月前
|
Go 开发者
|
3月前
|
存储 消息中间件 缓存
|
4月前
|
存储 关系型数据库 文件存储
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
面试题MySQL问题之简单的SELECT操作在MVCC下加锁如何解决
47 2
|
4月前
|
自然语言处理 Go 数据处理
云计算自旋锁问题之引入Golang插件系统后iLogtail的输入输出通道和处理能力如何解决
云计算自旋锁问题之引入Golang插件系统后iLogtail的输入输出通道和处理能力如何解决
36 1
|
5月前
|
监控 Go
博客园 ☜ golang select 的 case 执行顺序
Go 语言的 `select` 语句用于等待多个通道操作就绪。当非阻塞的 chan1, chan2, chan3 同时可读时,`select` 会随机选择一个执行,之后的循环中其他未选中的 case 仍有执行机会。如果所有 case 都未准备好,将执行 default case。
|
6月前
|
Go
golang力扣leetcode 面试题01.05.一次编辑
golang力扣leetcode 面试题01.05.一次编辑
56 0