jinc09
jinc09

Reputation: 9

Confusing performance about two pieces of code with go goroutines

Here is a piece of code, the printed value of x is an indeterminate integer, eg: x = 359931570 , x = 325604846. The performance is expected.

package main

import (
        "fmt"
        "runtime"
        "time"
)

func main() {
        runtime.GOMAXPROCS(1)
        var x int = 1
        for i := 0; i < 2; i++ {
                go func() {
                        for {
                            x=add(x) // x=x+1 
                        }
                }()
        }
        time.Sleep(time.Second)
        fmt.Println("end")
        fmt.Println("x =", x)
}

func add(x int) int {
  return x+1
}

But if I replace x=add(x) with x=x+1 in the code, its output becomes always x = 1. It looks like the code in the goroutine is not executed. I can't understand this behavior, what is the explanation?

Upvotes: 0

Views: 130

Answers (1)

Burak Serdar
Burak Serdar

Reputation: 51542

The code has a data race, and the output is undefined. However, there is a way to explain why x=1 at the end.

With multiple goroutines updating the shared variable x with no explicit synchronization, there are no guarantees that other goroutines will see the updates to the variable x made by one goroutine. Thus the Go memory model allows the case where the main goroutine never sees the effects of the other goroutines, and uses the initial value of x.

Why that changes when a function is used is interesting. But then, there is a data race and the output is undefined.

Upvotes: 4

Related Questions