下面开始进入 包的学习:
1、golang中的包
a、golang目前有150个标注你的包,覆盖了几乎所有的基础库。
b、golang.org有所有包的文档。
2、线程同步:
a、import("sync")
b、互斥锁,var mu sync.Mutex: 写多读少的情况下,用互斥锁。
c、读写锁, var mu sync.RWMutex:读多写少的情况下,用读写锁。
利用go build --help查看帮助,比如其中的 -race 就可以查看是否有竞争关系。(有的话就要加上锁)
package main
import (
"fmt"
//"sync"
"math/rand"
"time"
)
func testMap() {
var a map[int]int
a = make(map[int]int)
a[8] = 10
a[1] = 10
a[3] = 10
a[5] = 10
a[11] = 10
for i := 0;i <2;i++ {
go func(b map[int]int) {
b[1] = rand.Intn(100)
fmt.Println(b)
}(a)
}
time.Sleep(3* time.Second)
fmt.Println(a)
}
func main() {
testMap()
}
直接运行结果: 会发现,key1:81 key1:87 两个值。
PS F:\go\src\go_dev> .\main.exe
map[8:10 1:81 3:10 5:10 11:10]
map[8:10 1:87 3:10 5:10 11:10]
map[8:10 1:87 3:10 5:10 11:10]
PS F:\go\src\go_dev>
加参数编译后运行,就可以找到这个出现竞争的地方。告警是 data race。在第19行出现问题。
PS F:\go\src\go_dev> go build -race .\day4\work\example15\main\main.go
PS F:\go\src\go_dev> .\main.exe==================
WARNING: DATA RACE
Write at 0x00c042094150 by goroutine 7:
map[8:10 1:81 3:10 5:10 11:10]
runtime.mapassign_fast64()
E:/software/go/src/runtime/hashmap_fast.go:522 +0x0
main.testMap.func1()
F:/go/src/go_dev/day4/work/example15/main/main.go:20 +0x6f
(...略...)
example02:加个锁,然后再继续查看效果。lock.lock() 与 lock.unlock() 之间的代码会上锁。其中 goroutine与后面读的部分,都要进行上锁。
package main
import (
"fmt"
"sync"
"math/rand"
"time"
)
var lock sync.Mutex
func testMap() {
...
for i := 0;i <2;i++ {
go func(b map[int]int) {
lock.Lock()
b[1] = rand.Intn(100)
fmt.Println(b)
lock.Unlock()
}(a)
}
time.Sleep(3* time.Second)
lock.Lock()
fmt.Println(a)
lock.Unlock()
}
func main() {
testMap()
}
重新编译后运行结果:发现不报错了,互斥锁也就意味着,同一时间,只能有一个读。
PS F:\go\src\go_dev> go build -race .\day4\work\example15\main\main.go
PS F:\go\src\go_dev> .\main.exe
map[5:10 11:10 8:10 1:81 3:10]
map[3:10 5:10 11:10 8:10 1:87]
map[1:87 3:10 5:10 11:10 8:10]
PS F:\go\src\go_dev>
example03:读写锁,读多写少的情况下,用读写锁。读写锁,互斥锁性能测试:读写锁910w,互斥锁480w,性能差一倍。
package main
import (
"sync/atomic"
"fmt"
"sync"
//"math/rand"
"time"
)
var lock sync.Mutex
var rwLock sync.RWMutex
func testMap() {
var a map[int]int
var count int32
a = make(map[int]int)
a[8] = 10
a[1] = 10
a[3] = 10
a[5] = 10
a[11] = 10
for i := 0;i < 10; i++ {
go func(b map[int]int) {
for {
//rwLock.RLock()
lock.Lock()
//fmt.Println(b)
atomic.AddInt32(&count,1)
//rwLock.RUnlock()
lock.Unlock()
}
}(a)
}
time.Sleep(3* time.Second)
fmt.Println(atomic.LoadInt32(&count))
}
func main() {
testMap()
}
运行结果:
PS F:\go\src\go_dev> go build -race .\day4\work\example15\main\main.go
PS F:\go\src\go_dev> .\main.exe
9119799
PS F:\go\src\go_dev>
PS F:\go\src\go_dev> go build -race .\day4\work\example15\main\main.go
PS F:\go\src\go_dev> .\main.exe
4827222
PS F:\go\src\go_dev>
2019年12月9号 来北京的第35天,今天雾霾有点重,不宜外出
已经慢慢走出了离家的忧愁,开始投入到工作中了,也开始明白了奋斗的意义。
今天由于雾霾,没有去公司加班,在酒店看golang的视频教程,另外逻辑英语的思路不错,很多东西只要懂了原理,就好处理了,不断重复不是机械的重复,而是带着思考,在重复中学习到新的知识才有意义,不然纯粹是在浪费时间。
一定要让自己忙起来,不然,就会留下滋生脆弱土壤。
成长是一条漫长而缓慢的道路,是一个美好不断破灭的过程,但也会有新的认知,等到回首时,一切都成为过往,留下的回忆,经历都是美好的。