Skip to content

Instantly share code, notes, and snippets.

@border
Created October 25, 2012 03:28

Revisions

  1. border revised this gist Oct 25, 2012. 1 changed file with 36 additions and 0 deletions.
    36 changes: 36 additions & 0 deletions diff.diff
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    ~ ✗ 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
    }
  2. border revised this gist Oct 25, 2012. 2 changed files with 8 additions and 8 deletions.
    6 changes: 3 additions & 3 deletions mutex.go
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ func (m *Msg) InitMsg(key int64, value string) {
    }

    func (m *Msg) Get(key int64, c chan bool) (str string) {
    defer func(){ <-c }()
    defer func() { <-c }()
    m.mutex.Lock()
    if _, ok := m.count[key]; !ok {
    m.mutex.Unlock()
    @@ -40,13 +40,13 @@ func main() {
    runtime.GOMAXPROCS(runtime.NumCPU() * 2)
    msg := &Msg{count: map[int64]string{}}
    var i int64
    c := make(chan bool, 2000)
    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
    c <- true
    go msg.Get(i, c)
    }
    t2 := time.Now().UnixNano()
    10 changes: 5 additions & 5 deletions mutexv2.go
    Original file line number Diff line number Diff line change
    @@ -10,8 +10,8 @@ import (

    type Msg struct {
    rmutex sync.RWMutex
    mutex sync.Mutex
    count map[int64]string
    mutex sync.Mutex
    count map[int64]string
    }

    func (m *Msg) InitMsg(key int64, value string) {
    @@ -21,7 +21,7 @@ func (m *Msg) InitMsg(key int64, value string) {
    }

    func (m *Msg) Get(key int64, c chan bool) (str string) {
    defer func(){ <-c }()
    defer func() { <-c }()
    m.rmutex.RLock()
    if _, ok := m.count[key]; !ok {
    m.rmutex.RUnlock()
    @@ -41,13 +41,13 @@ func main() {
    runtime.GOMAXPROCS(runtime.NumCPU() * 2)
    msg := &Msg{count: map[int64]string{}}
    var i int64
    c := make(chan bool, 2000)
    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
    c <- true
    go msg.Get(i, c)
    }
    t2 := time.Now().UnixNano()
  3. border created this gist Oct 25, 2012.
    54 changes: 54 additions & 0 deletions mutex.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    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)
    }
    55 changes: 55 additions & 0 deletions mutexv2.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,55 @@
    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)
    }
    4 changes: 4 additions & 0 deletions 测试结果
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    ~ ✗ go run mutex.go
    7566709000
    ~ ✗ go run mutexv2.go
    3387533000