为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 3 秒内打印出这个 Go 代码?

如何在 3 秒内打印出这个 Go 代码?

Go
www说 2022-06-27 10:05:49
这是 Go 代码 https://www.intervue.io/sandbox-ILSCXZ6RRfunc worker() chan int {   ch := make(chan int)   go func() {      time.Sleep(3 * time.Second)      ch <- 42   }()   return ch}func main() {   timeStart := time.Now()   _, _ = <-worker(), <-worker()   println(int(time.Since(timeStart).Seconds())) // 3 or 6 ?}我怎样才能让它在 3 秒内执行而不是在 6 秒内执行?
查看完整描述

2 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

这需要 6 秒,因为您正在从返回的通道接收worker(),因此在worker()从第一个接收到值之前,第二个无法启动,这需要 3 秒。

您正在使用元组分配。规格:作业:

任务分两个阶段进行。首先,左侧的索引表达式指针间接(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序进行计算。其次,作业是按从左到右的顺序进行的。

规格:评估顺序:

...当计算表达式、赋值或返回语句的操作数时,所有函数调用、方法调用和通信操作都按词法从左到右的顺序计算

先启动 2 个 worker,然后再从通道中接收,这样 goroutine 才能真正并发运行:

ch1, ch2 := worker(), worker()_, _ = <-ch1, <-ch2

有了这个,输出将是(在Go Playground上尝试):

3


查看完整回答
反对 回复 2022-06-27
?
Cats萌萌

TA贡献1805条经验 获得超9个赞

您也可以删除通道,因为您没有使用通道的结果,只需使用 sync.WaitGroup


func worker(n int, wg *sync.WaitGroup) {

    defer wg.Done()

    time.Sleep(3 * time.Second)

    fmt.Println("done")

}


func main() {

    timeStart := time.Now()

    var wg sync.WaitGroup


    for i := 0; i <= 1; i++ {

        wg.Add(1)

        go worker(i, &wg)

    }

    wg.Wait()


    fmt.Println(int(time.Since(timeStart).Seconds())) // 3

}

这是示例代码: https: //play.golang.org/p/9_Ymx0tcHqS


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号