Created
June 13, 2021 10:00
-
-
Save ercang/ef03b7cae53d85a87df06ce17a81df3d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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