package main
import "fmt"
func square(c chan int) {
fmt.Println("[square] reading")
num := <-c
fmt.Println("[square] before writing")
c <- num * num
fmt.Println("[square] after writing")
}
func cube(c chan int) {
fmt.Println("[cube] reading")
num := <-c
fmt.Println("[cube] before writing")
c <- num * num * num
fmt.Println("[cube] after writing")
}
func main() {
fmt.Println("[main] main() started")
squareChan := make(chan int)
cubeChan := make(chan int)
go square(squareChan)
go cube(cubeChan)
testNum := 3
fmt.Println("[main] sent testNum to squareChan")
squareChan <- testNum
fmt.Println("[main] resuming")
fmt.Println("[main] sent testNum to cubeChan")
cubeChan <- testNum // Why main not blocked here?
fmt.Println("[main] resuming")
fmt.Println("[main] reading from channels")
squareVal, cubeVal := <-squareChan, <-cubeChan
sum := squareVal + cubeVal
fmt.Println("[main] sum of square and cube of", testNum, " is", sum)
fmt.Println("[main] main() stopped")
}
Why is it printed like that ??? Output:
1.[main] main() started
2. [main] sent testNum to squareChan
3. [cube] reading
4. [square] reading
5. [square] before writing
6. [main] resuming
7. [main] sent testNum to cubeChan
8. [main] resuming
9. [main] reading from channels
10. [square] after writing
11. [cube] before writing
12. [cube] after writing
13. [main] sum of square and cube of 3 is 36
14. [main] main() stopped
2 questions:
- Why after call "squareChan <- testNum" scheduler first check cube goroutine instead of square goroutine?
- Why after call "cubeChan <- testNum" main goroutine not blocked?
Please can somebody explain by steps - How exactly scheguler switch between square, cube and main goroutines in this code?
The scheduler isn't "checking" the
cuberoutine because of the write tosquareChan. Both goroutines are simply starting up, and havefmt.Printlnas the first logic.If you only want statements that say when something has been read, you'd need to place that after receiving from the channel.
You can't rely on consistent starting order for goroutines. There are no guarantees there.
If
squareChan <- testNumdidn't block, why would this one?The
cubegoroutine is waiting, blocked on receiving from the channel. When main writes to this channel, it's picked up immediately.If you're genuinely curious about what events are being sequenced, collecting a
traceprofile may be of interest.