Skip to content

Instantly share code, notes, and snippets.

@ercang
Created June 13, 2021 10:00
Show Gist options
  • Save ercang/ef03b7cae53d85a87df06ce17a81df3d to your computer and use it in GitHub Desktop.
Save ercang/ef03b7cae53d85a87df06ce17a81df3d to your computer and use it in GitHub Desktop.
package main
import (
"sync/atomic"
"time"
)
var sharedIntForAtomic int64 = 0
var unusedValueForAtomic int = 0
func runAtomicReader() {
for {
var val int64 = atomic.LoadInt64(&sharedIntForAtomic)
if val%10 == 0 {
unusedValueForAtomic = unusedValueForAtomic + 1
}
}
}
func runAtomicWriter() {
for {
atomic.AddInt64(&sharedIntForAtomic, 1)
}
}
func startAtomicReadWrite() {
go runAtomicReader()
go runAtomicWriter()
time.Sleep(10 * time.Second)
}
package main
import (
"context"
"fmt"
"sync"
"time"
)
var sharedMapForMutex map[string]int = map[string]int{}
var mapMutex = sync.Mutex{}
var mutexReadCount int64 = 0
func runMapMutexReader(ctx context.Context, readChan chan int) {
readCount := 0
for {
select {
case <-ctx.Done():
fmt.Println("reader exiting...")
readChan <- readCount
return
default:
mapMutex.Lock()
var _ int = sharedMapForMutex["key"]
mapMutex.Unlock()
readCount += 1
}
}
}
func runMapMutexWriter(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("writer exiting...")
return
default:
mapMutex.Lock()
sharedMapForMutex["key"] = sharedMapForMutex["key"] + 1
mapMutex.Unlock()
time.Sleep(100 * time.Millisecond)
}
}
}
func startMapMutexReadWrite() {
testContext, cancel := context.WithCancel(context.Background())
readCh := make(chan int)
sharedMapForMutex["key"] = 0
numberOfReaders := 15
for i := 0; i < numberOfReaders; i++ {
go runMapMutexReader(testContext, readCh)
}
go runMapMutexWriter(testContext)
time.Sleep(2 * time.Second)
cancel()
totalReadCount := 0
for i := 0; i < numberOfReaders; i++ {
totalReadCount += <-readCh
}
time.Sleep(1 * time.Second)
var counter int = sharedMapForMutex["key"]
fmt.Printf("[MUTEX] Write Counter value: %v\n", counter)
fmt.Printf("[MUTEX] Read Counter value: %v\n", totalReadCount)
}
package main
import "time"
// This is an example of race condition
// 2 goroutines tries to read&write sharedMap and there is no access control.
// This code should raise a panic condition
var sharedMap map[string]int = map[string]int{}
func runSimpleMapReader() {
for {
var _ int = sharedMap["key"]
}
}
func runSimpleMapWriter() {
for {
sharedMap["key"] = sharedMap["key"] + 1
}
}
func startMapReadWrite() {
sharedMap["key"] = 0
go runSimpleMapReader()
go runSimpleMapWriter()
time.Sleep(10 * time.Second)
}
package main
import (
"context"
"fmt"
"sync"
"time"
)
var sharedMapForRWMutex map[string]int = map[string]int{}
var mapRWMutex = sync.RWMutex{}
var rwMutexReadCount int64 = 0
func runMapRWMutexReader(ctx context.Context, readChan chan int) {
readCount := 0
for {
select {
case <-ctx.Done():
fmt.Println("reader exiting...")
readChan <- readCount
return
default:
mapRWMutex.RLock()
var _ int = sharedMapForRWMutex["key"]
mapRWMutex.RUnlock()
readCount += 1
}
}
}
func runMapRWMutexWriter(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("writer exiting...")
return
default:
mapRWMutex.Lock()
sharedMapForRWMutex["key"] = sharedMapForRWMutex["key"] + 1
mapRWMutex.Unlock()
time.Sleep(100 * time.Millisecond)
}
}
}
func startMapRWMutexReadWrite() {
testContext, cancel := context.WithCancel(context.Background())
readCh := make(chan int)
sharedMapForRWMutex["key"] = 0
numberOfReaders := 15
for i := 0; i < numberOfReaders; i++ {
go runMapRWMutexReader(testContext, readCh)
}
go runMapRWMutexWriter(testContext)
time.Sleep(2 * time.Second)
cancel()
totalReadCount := 0
for i := 0; i < numberOfReaders; i++ {
totalReadCount += <-readCh
}
time.Sleep(1 * time.Second)
var counter int = sharedMapForRWMutex["key"]
fmt.Printf("[RW MUTEX] Write Counter value: %v\n", counter)
fmt.Printf("[RW MUTEX] Read Counter value: %v\n", totalReadCount)
}
package main
import "time"
// This is an example of race condition
// 2 goroutines tries to read&write sharedInt and there is no access control.
var sharedInt int = 0
var unusedValue int = 0
func runSimpleReader() {
for {
var val int = sharedInt
if val%10 == 0 {
unusedValue = unusedValue + 1
}
}
}
func runSimpleWriter() {
for {
sharedInt = sharedInt + 1
}
}
func startSimpleReadWrite() {
go runSimpleReader()
go runSimpleWriter()
time.Sleep(10 * time.Second)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment