账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    Golang or-channel的模式递归理解问题
    37
    0

    关于Golang or-channle的模式,又多个协程并发,如果这些协程里面有一个结束,那么就是发出有关的消息,结束阻塞,相关的理解可以直接看代码。。我的问题在于:代码中向下递归的过程中,为什么还要添加本身的orDone这个chan interface(直接参照代码即可)。。这个模式来自《Concurrency programming with Go》书中的第四章的or-channel,希望有理解的同学可以解释一下,谢谢!!

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        // 从这里传入各个channel的done
        var or func(channels ...<-chan interface{}) <-chan interface{}
        or = func(channels ...<-chan interface{}) <-chan interface{} {
            switch (len(channels)) {
            case 0: // 递归结束的条件
                return nil
            case 1: // 只有一个直接返回
                return channels[0]
            }
            orDone := make(chan interface{})  /// 这里是问题中提到的interface
            go func() {
                defer close(orDone) // 结束的时候释放本身的done信号
                switch len(channels) {
                case 2:
                    select {
                    case <-channels[0]:
                    case <-channels[1]:
                    }
                default:
                    select {
                    case <-channels[0]:
                    case <-channels[1]:
                    case <-channels[2]:
                    // 问题在这里:为什么还要加入本身的orDone,这是我一直不明白的地方。。。
                    case <-or(append(channels[3:], orDone)...): 
                    }
                }
            }()
            return orDone
        }
    
        sig := func(after time.Duration) <-chan interface{} {
            c := make(chan interface{})  
            go func() {
                defer close(c) // 所在的goroutine结束后close,使用时间模拟工作时间
                time.Sleep(after)
            }()
            return c
        }
    
        start := time.Now()
        <-or(
            sig(2*time.Hour),
            sig(5*time.Minute),
            sig(1*time.Second),
            sig(1*time.Hour),
            sig(1*time.Minute),
        )
        fmt.Printf("done after %v\n", time.Since(start))
    }
    /*
    输出结果:
    done after 1.000182106s
    */
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部