Go map 互斥锁

本文代码github: https://github.com/zboyco/go-test/blob/master/lock.go


之前写go-server[https://github.com/zboyco/go-server] 的时候,需要把有效的客户端会话(session)放入一个map中保存,方便做超时处理,每间隔固定时间处理一次超时的会话,这就需要在处理的时候让其他的地方不能操作这个map,这就用到了锁(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
48
49
50
51
52
53
54
55
56
57
package main

import (
"fmt"
"sync"
"time"
)

type model struct {
m map[int]int
mutex sync.Mutex
}

func main() {
fmt.Println("测试开始")

obj := model{
m: make(map[int]int),
}

// 开启goroutine循环放开和锁住model
go lock(&obj)

// 开启goroutine循环插入新数据
go insert(&obj)

// 循环输出map内容长度
for {
fmt.Println(len(obj.m))
time.Sleep(time.Second)
}
}

// lock 锁住5秒,放开5秒
func lock(obj *model) {
for {
obj.mutex.Lock()
fmt.Println("锁住了...")
time.Sleep(5 * time.Second)
fmt.Println("解锁了...")
obj.mutex.Unlock()
time.Sleep(5 * time.Second)
}
}

// insert 循环插入新数据
func insert(obj *model) {
i := 0
for {
i++
obj.mutex.Lock()
obj.m[i] = i
obj.mutex.Unlock()
time.Sleep(time.Second)
}
}

输出结果如下

可以看到,在lock方法锁住model的5秒时间内,insert方法是不能插入新数据的,这就满足我的需求了,可以在锁住的时间内,做超时的处理了.