Search code examples
gotimeconcurrencychannelgoroutine

How to make this Go code print in 3 seconds?


Here is the Go code https://www.intervue.io/sandbox-ILSCXZ6RR

func 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 ?
}

How can I make this execute in 3 seconds rather than executing in 6 seconds?


Solution

  • It takes 6 seconds because you are receiving from the channel returned by worker(), so the 2nd worker() cannot be started until a value is received from the first, which takes 3 seconds.

    You are using a tuple assignment. Spec: Assignments:

    The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

    And Spec: Order of evaluation:

    ...when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order.

    Launch the 2 workers first, and then receive from the channels, so the goroutines can truly run concurrently:

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

    With this, output will be (try it on the Go Playground):

    3