
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 如果随机选择了执行定时器的代码,那么在这次 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 的情况 |
5 PlG5sBkXD1ziLeGB 2023-11-16 18:05:43 +08:00 via iPhone @yujianwjj #3 close 了还是可以一直读的 |
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 ,保证最多只执行一次就退出 |