Consider following code:
package main
import (
"fmt"
"sync"
)
func main() {
var a int
m := new(sync.Mutex)
wg := sync.WaitGroup{}
wg.Add(2)
go func(){
m.Lock()
a = 2
m.Unlock()
wg.Done()
}()
go func(){
//m.Lock()
a = 9
//m.Unlock()
wg.Done()
}()
wg.Wait()
fmt.Println(a)
}
if we run this code with -race flag we get warning that there is a race condition.
1) what can possibly go wrong with this race condition?
if we uncomment lock in second routine we don't get a race condition warning. But we can have different output so a race condition exists.
2) Why now we don't have a race condition warning?
1) what can possibly go wrong with this race condition?
2) Why now we don't have a race condition warning?
Mutex is a primitive which can guarantee atomicity. When lock is uncommented the runtime/os fully syncrhonizes access to the statement(s) that the lock protects. ie a
will never be set to both 2 and 9 at the same time.
There may be a performance implications here (your app may never run into them) because these are serialized operations. This is usually a fine tradeoff because it ensures correctness at the cost of potential performance implications.
The go documentation has amazing resources around the specifics of this issue:
Race condition occurs when two or more operations must execute in correct order,but they don't do so because of the way program is written.
data race: one concurrent operation attempts to read a variable while at some undetermined time another concurrent operation is attempting to write to the same variable.
This simple example have a data race, since we are reading a
and printing, where some other go-routine is trying to update the value.
package main
import "fmt"
func main() {
var a int
go func() {
a++
}()
if a == 0 {
fmt.Println("data:", a)
}
}
output possibilities:
a
is 1
,and it is printed( a
is 0
, while entering the if block, but by the time you print it changed.) a
is 0
, and it is printed(update didn't happen yet) a
is updated) Coming to your question:
1. what can possibly go wrong with this race condition?
Ans:
a
is undetermined, either it can be 2
or 9
.(if your first go func()
runs first, a will be 9
, if second func()
runs first, a
will be 2
). a
in second func()
, now first func()
runs and tries to update, function which wrote last to a
will determine the output.It can either be 2
or 9
once again. 2. Why now we don't have a race condition warning?
Ans:
Because now at any movement of time only one goroutine can access a
and update it. But even now a
is not deterministic, which ever func()
runs last will determine it. (even this a race-condition, one can overcome this with proper synchronization).
-race
cannot determine this type of race
conditions, because it's almost impossible to do so.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.