go select 的一个疑问

175 天前
 yujianwjj
func f() {
    for {
    	select {
        case <-stopCh:
            return
        case <-t.C():
            // do something
        }
    }
}

如果 定时器 和 stopCh 同时触发,然后随机执行了 定时器的代码,那么这个函数还会退出吗

1085 次点击
所在节点    Go 编程语言
8 条回复
nagisaushio
175 天前
下一次循环就退出了
meowoo
175 天前
如果随机选择了执行定时器的代码,那么在这次 select 语句执行完毕之后,函数会再次进入 select 语句的等待。如果此时 stopCh 依然是可用状态,那么下一次 select 可能会选择 stopCh 的案例,导致函数返回并退出。但如果 stopCh 在下一次选择前不再触发,函数将继续运行直到其中一个案例再次被触发。
yujianwjj
175 天前
stopCh 的触发是外部 close(stopCh)
varshonwood
175 天前
建议 do something 逻辑用异步,不然容易出现 stopCh 无法 return 的情况
yyf1234
175 天前
@yujianwjj #3 close 了还是可以一直读的
Vegetable
175 天前
当然会,golang 声称随机选择是公平的,所以不会一致执行定时器。总会随机到 stopCh 。如果处理的时间很长,为了比来多执行一次,我认为应该加一些逻辑优先判断当前退出状态,外边补一层 select stopCh
yujianwjj
175 天前
了解了,close 之后的 channel 依然可读
Ainokiseki
167 天前
这个特性确实很麻烦,所以我为了保证及时退出,都是在 t.C()这种业务分支下面再加一个 select 来判断 stopCh ,保证最多只执行一次就退出

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/992528

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX