Go, Select statement

package main

import (
"fmt"

)

func g1(ch chan int) {
ch <- 42`

}

func g2(ch chan int) {
ch <- 43
}

func main() {

ch1 := make(chan int)
ch2 := make(chan int)

go g1(ch1)
go g1(ch2)

select {
case v1 := <-ch1:
    fmt.Println("Got: ", v1)
case v2 := <-ch2:
    fmt.Println("Got: ", v2)
default:
    fmt.Println("The default case!")
}

}
Why does when I launch this code I take default answer every time?

Probably because neither goroutine have been scheduled so far to be able to send something, try adding some minimal sleep to force a reschedule to another go routine

@NobbZ is correct. The minimal time required for a go routine to do any valuable task is 10ms. Try adding some time sleep. It will work.

But if I delete default condition it’s work correctly. Why is it?

This is what happens in both situations, until the select is hit:

  1. Prepare channels
  2. start 1. goroutine
  3. start 2. goroutine

Now with default clause:

  1. Neither ch1 nor ch2 currently hold data, as no other gorotine had time do send something
  2. default is “selected”.

Without default:

  1. Neither ch1 nor ch2 currently hold data, as no other gorotine had time do send something
  2. But there is no default, this go routine has no way to continue without having received data from any channel, so it puts itself to sleep and hands over the control to the scheduler
  3. the scheduler randomly hands over control to one of the go routines marked as “ready to continue”.
  4. This will send instantly send data over “its” channel back to the main go routine.
  5. Hands back to scheduler
  6. scheduler knows that the main routine could continue, though it still selects randomly between the main routine and the other pending sender. (therefore the other sender might or might not put something in the channel)
  7. Main got control directly or later, and now picks randomly from one of the available channels.
1 Like

Thank you.It is helpful answer