Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mikemadisonweb/4ae7f2b697fa32b135c9ab50699c5b77 to your computer and use it in GitHub Desktop.
Save mikemadisonweb/4ae7f2b697fa32b135c9ab50699c5b77 to your computer and use it in GitHub Desktop.
Understand Race Condition with Go
package main
import (
"fmt"
"time"
"sync/atomic"
)
var start time.Time
var elapsed time.Duration
var channel chan bool
var counter int
func DoCount (duration time.Duration) {
value := counter
time.Sleep(duration)
value++
counter = value
}
func main() {
// ==============================================================
// Case non maintain race condition, task done in 1 nano second
// ==============================================================
counter = 0
start = time.Now()
// Simulate 1000 async requests from client side before listen command
for request := 1; request <= 1000; request++ {
go func () {
DoCount(1*time.Nanosecond)
}()
}
elapsed = time.Since(start)
// Wait for ensure result
time.Sleep(1*time.Second)
fmt.Println("==================================================================")
fmt.Println("Case non maintain race condition, task done in 1 nano second")
fmt.Println("counter = ", counter)
fmt.Println("spend time = ", elapsed)
// ==============================================================
// Case non maintain race condition, task done in 1 milli second
// ==============================================================
counter = 0
start = time.Now()
// Simulate 1000 async requests from client side before listen command
for request := 1; request <= 1000; request++ {
go func () {
DoCount(10*time.Millisecond)
}()
}
elapsed = time.Since(start)
// Wait for ensure result
time.Sleep(1*time.Second)
fmt.Println("==================================================================")
fmt.Println("Case non maintain race condition, task done in 1 milli second")
fmt.Println("counter = ", counter)
fmt.Println("spend time = ", elapsed)
// ==============================================================
// Case maintain race condition, task done in 1 nano second
// ==============================================================
counter = 0
start = time.Now()
channel = make(chan bool)
// Simulate 1000 async requests from client side before listen command
for request := 1; request <= 1000; request++ {
go func () {
channel <- true
}()
}
// Simulate replay task spend time 2 seconds
time.Sleep(time.Second * 2)
// Start listen command after replay task
go func() {
for {
<-channel
DoCount(1*time.Nanosecond)
}
}()
elapsed = time.Since(start)
// Wait for ensure result
time.Sleep(1*time.Second)
fmt.Println("==================================================================")
fmt.Println("Case maintain race condition, task done in 1 nano second")
fmt.Println("counter = ", counter)
fmt.Println("spend time = ", elapsed)
// ==============================================================
// Case atomic add race condition, task done fastest
// ==============================================================
var atomicCounter uint64 = 0
counter = 0
start = time.Now()
// Simulate 1000 async requests from client side before listen command
for request := 1; request <= 1000; request++ {
go func () {
counter++
atomic.AddUint64(&atomicCounter, 1)
}()
}
elapsed = time.Since(start)
// Wait for ensure result
time.Sleep(1*time.Second)
fmt.Println("==================================================================")
fmt.Println("Case atomic add race condition, task done fastest")
fmt.Println("counter = ", counter)
fmt.Println("atomicCounter = ", atomicCounter)
fmt.Println("spend time = ", elapsed)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment