DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

Golang Rlock

原文链接

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
package main

import (
"fmt"
"os"
"runtime/trace"
"sync"
"time"
)

var mlock sync.RWMutex
var wg sync.WaitGroup

func main() {
trace.Start(os.Stderr)
defer trace.Stop()
wg.Add(100)

for i := 0; i < 100; i++ {
go gets()
}

wg.Wait()
}

func gets() {
for i := 0; i < 100000; i++ {
get(i)
}
wg.Done()
}

func get(i int) {
beginTime := time.Now()
mlock.RLock()
tmp1 := time.Since(beginTime).Nanoseconds() / 1000000
if tmp1 > 100 { // 超过100ms就打印出来
fmt.Println("fuck here")
}
mlock.RUnlock()
}

RLock 本身是一个很轻量的操作(atomic.AddInt32),不太可能会出现超出加个 RLock 超过 100ms 情况出现,除非和写锁频繁冲突。

在命令行执行 go run back2.go 2> trace,发现还是可能出现 **** here

blocking syscall

结论:写代码的话,Lock 内尽量不要有 syscall(哪怕是 time.Now,time.Since 这种计时行为),RLock 也一样(虽然有时候确实避免不了)。