# GO语言学习笔记-互斥锁

```x = x+1
```

1. 获取当前的x值
2. 计算x+1
3. 把上一步的结果赋值给x

## 互斥锁

```mutex.Lock()
x = x + 1
mutex.Unlock()
```

## 一段有竞争条件的代码

```package main
import (
"fmt"
"sync"
)
var x  = 0
func increment(wg *sync.WaitGroup) {
x = x + 1
wg.Done()
}
func main() {
var w sync.WaitGroup
for i := 0; i < 1000; i++ {
go increment(&w)
}
w.Wait()
fmt.Println("final value of x", x)
}
```

`increment` 函数将x自增1然后调用 `wg.Done()` 来通知 `WaitGroup` 完成，然后通过循环生成1000个goroutine，每个goroutine都是并发执行并且并发获取x的值。多次运行程序，你会发现结果每次都不同，比如 `value of x 941``final value of x 928``final value of x 922` 等。

## 使用互斥锁解决问题

```package main
import (
"fmt"
"sync"
)
var x  = 0
func increment(wg *sync.WaitGroup, m *sync.Mutex) {
m.Lock()
x = x + 1
m.Unlock()
wg.Done()
}
func main() {
var w sync.WaitGroup
var m sync.Mutex
for i := 0; i < 1000; i++ {
go increment(&w, &m)
}
w.Wait()
fmt.Println("final value of x", x)
}
```

```final value of x 1000
```

## 使用channel解决问题

```package main
import (
"fmt"
"sync"
)
var x  = 0
func increment(wg *sync.WaitGroup, ch chan bool) {
ch <- true
x = x + 1
<- ch
wg.Done()
}
func main() {
var w sync.WaitGroup
ch := make(chan bool, 1)
for i := 0; i < 1000; i++ {
go increment(&w, ch)
}
w.Wait()
fmt.Println("final value of x", x)
}
```

## 互斥锁 vs Channel

(roy注:这段我就选重点翻译了)