共享内存并发机制
===
> 像java这样的语言实现并发就涉及共享资源,为了保证资源的安全性就要用到锁
go 并发之间的通讯可以用channel吧并行数据转变为串行数据,我们还是向讲一讲老的处理方案
### Package Sync包中有两个锁
一个是Mutex 互斥写锁
一个是RWLock 读写锁
没有锁的下场
~~~
func TestCounter(t *testing.T) {
counter := 0
var wg sync.WaitGroup
for i := 0;i<5000;i++ {
wg.Add(1)
go func() {
counter++
wg.Done()
}()
}
wg.Wait()
t.Log(counter)
}
~~~
![](https://box.kancloud.cn/00a94ed3dbda3f69129ecb46a08cc42a_729x631.png)
这个根本就不对阿!
哈哈哈 有可能几个协程同时写导致的
所以我们要使用锁来实现
我们向计算以下这个程序的时间
~~~
func TestCounter(t *testing.T) {
nowTime := time.Now().UnixNano()
counter := 0
var wg sync.WaitGroup
for i := 0;i<5000;i++ {
wg.Add(1)
go func() {
counter++
wg.Done()
}()
}
wg.Wait()
t.Log(counter)
tTime := time.Now().UnixNano()
fmt.Println("time: ",(tTime - nowTime))
}
~~~
这里用nano秒来计算,为什么了go太快了
现在测试结果是:
```
=== RUN TestCounter
time: 2071910
--- PASS: TestCounter (0.00s)
share_test.go:28: 4334
PASS
```
### 我们现在加上锁
~~~
func TestMutCounter(t *testing.T) {
nowTime := time.Now().UnixNano()
var nut sync.Mutex
counter := 0
var wg sync.WaitGroup
for i := 0;i<5000;i++ {
wg.Add(1)
go func() {
nut.Lock()
defer nut.Unlock()
counter++
wg.Done()
}()
}
wg.Wait()
t.Log(counter)
tTime := time.Now().UnixNano()
fmt.Println("time: ",(tTime - nowTime))
}
~~~
现在的返回结果
```
=== RUN TestMutCounter
time: 2151931
--- PASS: TestMutCounter (0.00s)
share_test.go:48: 5000
PASS
```
答案是对了但是大家有没有发现这个时间,比上一个没有加锁的时间多
这个就锁带来的性能消耗
为了解决这个问题我们用读写锁来实现一遍
看下面的RWMutex
- Hello World
- UDP
- UDP服务端
- UDP客户端
- UDP广播
- 错误处理
- 编写好的异常处理
- panic和recover
- 并发编程
- Hello Goruntine
- 共享内存并发机制
- RWMutex
- CSP并发机制
- 多路复用和超时控制
- 通道关闭与广播
- Context与任务的取消
- 只运行一次
- 按需任意任务完成
- 所有任务完成
- 补充:range channel注意实现
- 对象池
- sync.Pool临时对象池
- 单元测试
- 表格测试法
- Banchmark
- BDD
- 反射
- 利用反射编写灵活的代码
- Struct Tag
- 万能程序
- 常用架构模式
- Pipe-filter pattern
- Micro Kernel
- 性能分析
- 高性能代码
- sync.MAP分析
- Concurrent Map
- GC友好的代码
- Uber开发风格规范