Skip to content

Instantly share code, notes, and snippets.

@border
Created October 25, 2012 03:28
Show Gist options
  • Save border/3950259 to your computer and use it in GitHub Desktop.
Save border/3950259 to your computer and use it in GitHub Desktop.
Golang mutex and RWMutex 测试比较
~ ✗ diff -ruN mutex.go mutexv2.go
--- mutex.go 2012-10-25 11:30:04.170656858 +0800
+++ mutexv2.go 2012-10-25 11:30:04.174656858 +0800
@@ -9,8 +9,9 @@
)
type Msg struct {
- mutex sync.Mutex
- count map[int64]string
+ rmutex sync.RWMutex
+ mutex sync.Mutex
+ count map[int64]string
}
func (m *Msg) InitMsg(key int64, value string) {
@@ -21,15 +22,15 @@
func (m *Msg) Get(key int64, c chan bool) (str string) {
defer func() { <-c }()
- m.mutex.Lock()
+ m.rmutex.RLock()
if _, ok := m.count[key]; !ok {
- m.mutex.Unlock()
+ m.rmutex.RUnlock()
m.InitMsg(key, strconv.Itoa(int(key)))
} else {
- m.mutex.Unlock()
+ m.rmutex.RUnlock()
}
- m.mutex.Lock()
- defer m.mutex.Unlock()
+ m.rmutex.RLock()
+ defer m.rmutex.RUnlock()
if str, ok := m.count[key]; ok {
return str
}
package main
import (
"fmt"
"runtime"
"strconv"
"sync"
"time"
)
type Msg struct {
mutex sync.Mutex
count map[int64]string
}
func (m *Msg) InitMsg(key int64, value string) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.count[key] = value
}
func (m *Msg) Get(key int64, c chan bool) (str string) {
defer func() { <-c }()
m.mutex.Lock()
if _, ok := m.count[key]; !ok {
m.mutex.Unlock()
m.InitMsg(key, strconv.Itoa(int(key)))
} else {
m.mutex.Unlock()
}
m.mutex.Lock()
defer m.mutex.Unlock()
if str, ok := m.count[key]; ok {
return str
}
return
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU() * 2)
msg := &Msg{count: map[int64]string{}}
var i int64
c := make(chan bool, 2000)
t1 := time.Now().UnixNano()
for i = 0; i <= 1024000; i++ {
msg.InitMsg(i, strconv.Itoa(int(i)))
}
for i = 0; i <= 2048000; i++ {
c <- true
go msg.Get(i, c)
}
t2 := time.Now().UnixNano()
fmt.Println(t2 - t1)
}
package main
import (
"fmt"
"runtime"
"strconv"
"sync"
"time"
)
type Msg struct {
rmutex sync.RWMutex
mutex sync.Mutex
count map[int64]string
}
func (m *Msg) InitMsg(key int64, value string) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.count[key] = value
}
func (m *Msg) Get(key int64, c chan bool) (str string) {
defer func() { <-c }()
m.rmutex.RLock()
if _, ok := m.count[key]; !ok {
m.rmutex.RUnlock()
m.InitMsg(key, strconv.Itoa(int(key)))
} else {
m.rmutex.RUnlock()
}
m.rmutex.RLock()
defer m.rmutex.RUnlock()
if str, ok := m.count[key]; ok {
return str
}
return
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU() * 2)
msg := &Msg{count: map[int64]string{}}
var i int64
c := make(chan bool, 2000)
t1 := time.Now().UnixNano()
for i = 0; i <= 1024000; i++ {
msg.InitMsg(i, strconv.Itoa(int(i)))
}
for i = 0; i <= 2048000; i++ {
c <- true
go msg.Get(i, c)
}
t2 := time.Now().UnixNano()
fmt.Println(t2 - t1)
}
~ ✗ go run mutex.go
7566709000
~ ✗ go run mutexv2.go
3387533000
@oxbambooxo
Copy link

oxbambooxo commented Apr 9, 2017

go run mutexv2.go

will throw

fatal error: concurrent map read and map write

goroutine 1024111 [running]:
runtime.throw(0x10b6140, 0x21)
	/usr/local/Cellar/go/1.8/libexec/src/runtime/panic.go:596 +0x95 fp=0xc420fd9758 sp=0xc420fd9738
runtime.mapaccess2_fast64(0x109af60, 0xc4200720c0, 0xfa029, 0x102d388, 0x10b8560)
	/usr/local/Cellar/go/1.8/libexec/src/runtime/hashmap_fast.go:168 +0x1b2 fp=0xc420fd9780 sp=0xc420fd9758
main.(*Msg).Get(0xc420072090, 0xfa029, 0xc420086000, 0x0, 0x0)
	/Users/bamboo/Downloads/mutexv2.go:26 +0x9e fp=0xc420fd97b8 sp=0xc420fd9780
runtime.goexit()
	/usr/local/Cellar/go/1.8/libexec/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc420fd97c0 sp=0xc420fd97b8
created by main.main
	/Users/bamboo/Downloads/mutexv2.go:51 +0x1e1

goroutine 1 [runnable]:
main.main()
	/Users/bamboo/Downloads/mutexv2.go:50 +0x1ab

goroutine 1024224 [runnable]:
main.(*Msg).Get(0xc420072090, 0xfa09a, 0xc420086000, 0x0, 0x0)
	/Users/bamboo/Downloads/mutexv2.go:23
created by main.main
	/Users/bamboo/Downloads/mutexv2.go:51 +0x1e1

goroutine 1024314 [runnable]:
main.(*Msg).Get(0xc420072090, 0xfa0f4, 0xc420086000, 0x0, 0x0)
	/Users/bamboo/Downloads/mutexv2.go:23
created by main.main
	/Users/bamboo/Downloads/mutexv2.go:51 +0x1e1

goroutine 1024266 [runnable]:
main.(*Msg).Get(0xc420072090, 0xfa0c4, 0xc420086000, 0x0, 0x0)
	/Users/bamboo/Downloads/mutexv2.go:23
created by main.main
	/Users/bamboo/Downloads/mutexv2.go:51 +0x1e1

...

in the go version go1.8 darwin/amd64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment