Go 语言提供两类锁: 互斥锁(Mutex)和读写锁(RWMutex)。
其中读写锁(RWMutex)是基于互斥锁(Mutex)实现的,锁的定义源码:1
2
3
4
5
6
7
8
9
10
11
12
13type Mutex struct {
state int32
sema uint32
}
type Locker interface {
Lock()
Unlock()
}
func (m *Mutex) Lock()
func (m *Mutex) Unlock()
下面用代码来体现互斥锁的用处1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package main
import (
"fmt"
"sync"
)
func add(i *int){
for k :=0;k<10000000;k++{
*i ++
}
wg.Done()
}
func main(){
i := 0
go add(&i)
go add(&i)
wg.Add(2)
wg.Wait()
fmt.Println(i)
}
add 函数作用是传入的值加一千万次1,顺便引入go语法,golang语言中go是异步实现的关键词,使用go之后就可以将对应的函数放到goroutine中,由go自身的机制去异步执行,实现高并发,那么在这个代码中我的目的是为了将i增加到两千万,但是实际上使用goroutine后,i最后的结果只有一千多万,每次执行都有不同的结果,这就类似于python中使用多线程后会产生资源竞争的现象
这个时候就该互斥锁上场了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
28package main
import (
"fmt"
"sync"
)
var wg = sync.WaitGroup{}
var mutex = sync.Mutex{}
func add(i *int){
for k :=0;k<10000000;k++{
mutex.Lock()
*i ++
mutex.Unlock()
}
wg.Done()
}
func main(){
i := 0
go add(&i)
go add(&i)
wg.Add(2)
wg.Wait()
fmt.Println(i)
}
使用互斥锁后正确计算出了结果:20000000