Describe the mistake
In the description of "Expecting a deterministic behavior using select and channels (64)" , its written that the output of the code will be random :
0
1
2
disconnection, return
# or
0
disconnection, return
- But here, that situation doesn't arise because the disconnect send happens strictly after all message sends.
- the true output is not random , its always :
0
1
2
3
4
5
6
7
8
9
disconnection, return
- you will see the numbers 0–9 printed (in order), then "disconnection, return", and the program exits.
- the code snippet shows a goroutine that does two things in sequence:
- Sends integers 0 through 9 into
messageCh
- After the loop finishes, sends a signal into
disconnectCh
Meanwhile, the main loop continuously runs a select with two cases:
- receive from
messageCh
- receive from
disconnectCh
- Key detail: ordering guarantee
- Inside the goroutine, this part is strictly sequential:
- All
messageCh <- i sends happen first
- Only after the loop completes does
disconnectCh <- struct{}{} run
So the disconnect signal cannot happen before all numbers are sent.
- Pick
messageCh whenever a value is available
- Eventually pick
disconnectCh once that signal is sent
Because the disconnect happens after all sends, the loop will first consume all numbers.
Solution
Make the output non-deterministic
- Right now, the code is deterministic because:
- One goroutine sends values in order
disconnectCh only fires after all sends finish
- To make it “random”, you need multiple competing producers or race between channels.
- Example: multiple goroutines sending
for i := 0; i < 10; i++ {
go func(n int) {
messageCh <- n
}(i)
}
go func() {
// give time for sends to race
time.Sleep(time.Millisecond * 10)
disconnectCh <- struct{}{}
}()
for {
select {
case v := <-messageCh:
fmt.Println(v)
case <-disconnectCh:
fmt.Println("disconnection, return")
return
}
}
What changes?
- Now 10 goroutines are sending concurrently
- Order becomes non-deterministic
Describe the mistake
In the description of "Expecting a deterministic behavior using select and channels (64)" , its written that the output of the code will be random :
0 1 2 3 4 5 6 7 8 9 disconnection, returnmessageChdisconnectChMeanwhile, the main loop continuously runs a select with two cases:
messageChdisconnectChmessageCh <- isends happen firstdisconnectCh <- struct{}{}runSo the disconnect signal cannot happen before all numbers are sent.
messageChwhenever a value is availabledisconnectChonce that signal is sentBecause the disconnect happens after all sends, the loop will first consume all numbers.
Solution
Make the output non-deterministic
disconnectChonly fires after all sends finishWhat changes?