func f() {
for {
select {
case <-stopCh:
return
case <-t.C():
// do something
}
}
}
如果 定时器 和 stopCh 同时触发,然后随机执行了 定时器的代码,那么这个函数还会退出吗
1
nagisaushio 2023-11-16 17:54:50 +08:00 via Android
下一次循环就退出了
|
2
meowoo 2023-11-16 17:56:32 +08:00 1
如果随机选择了执行定时器的代码,那么在这次 select 语句执行完毕之后,函数会再次进入 select 语句的等待。如果此时 stopCh 依然是可用状态,那么下一次 select 可能会选择 stopCh 的案例,导致函数返回并退出。但如果 stopCh 在下一次选择前不再触发,函数将继续运行直到其中一个案例再次被触发。
|
3
yujianwjj OP stopCh 的触发是外部 close(stopCh)
|
4
varshonwood 2023-11-16 17:59:49 +08:00
建议 do something 逻辑用异步,不然容易出现 stopCh 无法 return 的情况
|
6
Vegetable 2023-11-16 18:34:34 +08:00
当然会,golang 声称随机选择是公平的,所以不会一致执行定时器。总会随机到 stopCh 。如果处理的时间很长,为了比来多执行一次,我认为应该加一些逻辑优先判断当前退出状态,外边补一层 select stopCh
|
7
yujianwjj OP 了解了,close 之后的 channel 依然可读
|
8
Ainokiseki 2023-11-24 16:26:59 +08:00
这个特性确实很麻烦,所以我为了保证及时退出,都是在 t.C()这种业务分支下面再加一个 select 来判断 stopCh ,保证最多只执行一次就退出
|