Go并发编程实战课

Concurrent Concepts

  • 互斥锁 Mutex
    • go race detector (c++ sanitizers)
    • wrong usage cases
      • lock/unlock 非成对出现
      • Copy 已使用的 Mutex
      • 重入
      • 死锁

Code Samples

Recursive Mutex

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import (
    "fmt"
    "runtime"
    "strings"
    "sync"
    "sync/atomic"
)

func getGID() int64 {
    b := make([]byte, 64)
    b = b[:runtime.Stack(b, false)]
    b = b[:strings.Index(string(b), " ")]
    b = b[10:]
    var gid int64
    fmt.Sscanf(string(b), "%d", &gid)
    return gid
}

type RecursiveMutex struct {
    sync.Mutex
    owner     int64
    recursion uint32
}

func (rm *RecursiveMutex) Lock() {
    gid := getGID()
    if atomic.LoadInt64(&rm.owner) == gid {
        rm.recursion++
        return
    }
    rm.Mutex.Lock()
    atomic.StoreInt64(&rm.owner, gid)
    rm.recursion = 1
}

func (rm *RecursiveMutex) UnLock() {
    gid := getGID()
    if atomic.LoadInt64(&rm.owner) != gid {
        panic(fmt.Sprintf("wrong owner(%d): %d!", rm.owner, gid))
    }
    rm.recursion--
    if rm.recursion != 0 {
        return
    }
    atomic.StoreInt64(&rm.owner, -1)
    rm.Mutex.Unlock()
}
Get Things Done
Built with Hugo
Theme Stack designed by Jimmy