MCPcopy
hub / github.com/hoanhan101/ultimate-go / main

Function main

go/concurrency/data_race_1.go:42–84  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

40var counter int
41
42func main() {
43 // Number of Goroutines to use.
44 const grs = 2
45
46 // wg is used to manage concurrency.
47 var wg sync.WaitGroup
48 wg.Add(grs)
49
50 // Create two Goroutines.
51 // They loop twice: perform a read to a local counter, increase by 1, write it back to the shared state
52 // Every time we run the program, the output should be 4.
53 // The data races that we have here is that: at any given time, both Gooutines could be reading
54 // and writing at the same time. However, we are very lucky in this case. What we are seeing it
55 // that, each Goroutine is executing the 3 statements atomically completely by accident every
56 // time this code run.
57 // If we put the line runtime.Gosched(), it will tell the scheduler to be part of the
58 // cooperation here and yield my time on that m. This will force the data race to happen. Once
59 // we read the value out of that shared state, we are gonna force the context switch. Then we
60 // come back, we are not getting 4 as frequent.
61 for i := 0; i < grs; i++ {
62 go func() {
63 for count := 0; count < 2; count++ {
64 // Capture the value of Counter.
65 value := counter
66
67 // Yield the thread and be placed back in queue.
68 // FOR TESTING ONLY! DO NOT USE IN PRODUCTION CODE!
69 runtime.Gosched()
70
71 // Increment our local value of Counter.
72 value++
73
74 // Store the value back into Counter.
75 counter = value
76 }
77 wg.Done()
78 }()
79 }
80
81 // Wait for the goroutines to finish.
82 wg.Wait()
83 fmt.Println("Final Counter:", counter)
84}

Callers

nothing calls this directly

Calls 2

AddMethod · 0.80
WaitMethod · 0.65

Tested by

no test coverage detected