V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yujianwjj
V2EX  ›  Go 编程语言

go select 的一个疑问

  •  
  •   yujianwjj · 2023-11-16 17:51:28 +08:00 · 1330 次点击
    这是一个创建于 371 天前的主题,其中的信息可能已经有所发展或是发生改变。
    func f() {
        for {
        	select {
            case <-stopCh:
                return
            case <-t.C():
                // do something
            }
        }
    }
    

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

    8 条回复    2023-11-24 16:26:59 +08:00
    nagisaushio
        1
    nagisaushio  
       2023-11-16 17:54:50 +08:00 via Android
    下一次循环就退出了
    meowoo
        2
    meowoo  
       2023-11-16 17:56:32 +08:00   ❤️ 1
    如果随机选择了执行定时器的代码,那么在这次 select 语句执行完毕之后,函数会再次进入 select 语句的等待。如果此时 stopCh 依然是可用状态,那么下一次 select 可能会选择 stopCh 的案例,导致函数返回并退出。但如果 stopCh 在下一次选择前不再触发,函数将继续运行直到其中一个案例再次被触发。
    yujianwjj
        3
    yujianwjj  
    OP
       2023-11-16 17:58:25 +08:00
    stopCh 的触发是外部 close(stopCh)
    varshonwood
        4
    varshonwood  
       2023-11-16 17:59:49 +08:00
    建议 do something 逻辑用异步,不然容易出现 stopCh 无法 return 的情况
    yyf1234
        5
    yyf1234  
       2023-11-16 18:05:43 +08:00 via iPhone
    @yujianwjj #3 close 了还是可以一直读的
    Vegetable
        6
    Vegetable  
       2023-11-16 18:34:34 +08:00
    当然会,golang 声称随机选择是公平的,所以不会一致执行定时器。总会随机到 stopCh 。如果处理的时间很长,为了比来多执行一次,我认为应该加一些逻辑优先判断当前退出状态,外边补一层 select stopCh
    yujianwjj
        7
    yujianwjj  
    OP
       2023-11-16 19:07:29 +08:00 via iPhone
    了解了,close 之后的 channel 依然可读
    Ainokiseki
        8
    Ainokiseki  
       363 天前
    这个特性确实很麻烦,所以我为了保证及时退出,都是在 t.C()这种业务分支下面再加一个 select 来判断 stopCh ,保证最多只执行一次就退出
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1908 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 16:20 · PVG 00:20 · LAX 08:20 · JFK 11:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.