I am absolute newbie to concurrency in Go. I was trying to produce race condition with two gouroutines and wrote the following code:
var x int = 2
func main() {
go f1(&x)
go f2(&x)
time.Sleep(time.Second)
fmt.Println("Final value of x:", x)
}
func f1(px *int) {
for i := 0; i < 10; i++ {
*px = *px * 2
fmt.Println("f1:", *px)
}
}
func f2(px *int) {
for i := 0; i < 10; i++ {
*px = *px + 1
fmt.Println("f2:", *px)
}
}
And in each variant of output there are all the f2's output lines in console and only after that there are f1's outputs. Here's an example:
f2: 3
f2: 4
f2: 5
f2: 6
f2: 7
f2: 8
f2: 9
f2: 10
f2: 21
f2: 22
f1: 20
f1: 44
f1: 88
f1: 176
f1: 352
f1: 704
f1: 1408
f1: 2816
f1: 5632
f1: 11264
Final value of x: 11264
But you can see that indeed some of f1's executions were made in between of f2's executions:
f2: 10
f2: 21
So that i have two questions:
- Why all the Printl() of f1 executes strictly after execution of f2's Println() (I thought they must be mixed somehow)
- Why when I change the order of goroutines in the code
go f2(&x)
go f1(&x)
instead of
go f1(&x)
go f2(&x)
the order of output lines changes vice versa, f1's first, f2'2 second. I mean how the order of gouroutines in code affects their execution?