go select 的一个疑问

2023-11-16 17:51:28 +08:00
 yujianwjj
func f() {
    for {
    	select {
        case <-stopCh:
            return
        case <-t.C():
            // do something
        }
    }
}

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

1366 次点击
所在节点    Go 编程语言
8 条回复
nagisaushio
2023-11-16 17:54:50 +08:00
下一次循环就退出了
meowoo
2023-11-16 17:56:32 +08:00
如果随机选择了执行定时器的代码,那么在这次 select 语句执行完毕之后,函数会再次进入 select 语句的等待。如果此时 stopCh 依然是可用状态,那么下一次 select 可能会选择 stopCh 的案例,导致函数返回并退出。但如果 stopCh 在下一次选择前不再触发,函数将继续运行直到其中一个案例再次被触发。
yujianwjj
2023-11-16 17:58:25 +08:00
stopCh 的触发是外部 close(stopCh)
varshonwood
2023-11-16 17:59:49 +08:00
建议 do something 逻辑用异步,不然容易出现 stopCh 无法 return 的情况
yyf1234
2023-11-16 18:05:43 +08:00
@yujianwjj #3 close 了还是可以一直读的
Vegetable
2023-11-16 18:34:34 +08:00
当然会,golang 声称随机选择是公平的,所以不会一致执行定时器。总会随机到 stopCh 。如果处理的时间很长,为了比来多执行一次,我认为应该加一些逻辑优先判断当前退出状态,外边补一层 select stopCh
yujianwjj
2023-11-16 19:07:29 +08:00
了解了,close 之后的 channel 依然可读
Ainokiseki
2023-11-24 16:26:59 +08:00
这个特性确实很麻烦,所以我为了保证及时退出,都是在 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