有那些网站做结伴旅游的,wordpress 本地部署,想把比尔的网站封了如何做,网络营销课程多少钱GO系列
1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…GO系列
1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Http) 11、GO学习之 微框架(Gin) 12、GO学习之 数据库(mysql) 13、GO学习之 数据库(Redis) 14、GO学习之 搜索引擎(ElasticSearch) 15、GO学习之 消息队列(Kafka) 16、GO学习之 远程过程调用(RPC) 17、GO学习之 goroutine的调度原理 18、GO学习之 通道(nil Channel妙用) 19、GO学习之 同步操作sync包 20、GO学习之 互斥锁、读写锁该如何取舍 文章目录 GO系列前言一、互斥锁性能测试二、读写锁性能测试三、小结 前言
按照公司目前的任务go 学习是必经之路了虽然行业卷不过技多不压身依旧努力 sync包提供了两种锁互斥锁Mutex和 读写锁RWMutex一般有推荐用 互斥锁它常被用来对结构体对象的内部状态、缓存等进行保护使用最为广泛。相比之下读写锁则使用率就不是那么多了但既然存在那就有存在的道理和使用场景。
一、互斥锁性能测试
先通过下面一个示例来看一下互斥锁在 cpu 2 4 8 16 32 的情况下怎么样。 下面的示例中首先声明一个全局变量 cs 来作为需要保护的临界区数据声明一个互斥锁对象 mu测试函数 BenchmarkReadByMutex 中利用 testing 测试包来执行完成测试并发执行。
package mainimport (synctesting
)// 模拟临界区需要保护的数据
var cs 0// 声明互斥锁
var mu sync.Mutexfunc BenchmarkReadByMutex(b *testing.B) {b.RunParallel(func(p *testing.PB) {for p.Next() {mu.Lock()_ csmu.Unlock()}})
}测试结果如下
PS D:\workspaceGo go test -bench . .\src\sync\sync_mutex_test.go -cpu 2
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByMutex-2 75139947 15.35 ns/op
PASS
ok command-line-arguments 1.418s
PS D:\workspaceGo go test -bench . .\src\sync\sync_mutex_test.go -cpu 4
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByMutex-4 48514642 23.85 ns/op
PASS
ok command-line-arguments 1.479s
PS D:\workspaceGo go test -bench . .\src\sync\sync_mutex_test.go -cpu 8
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByMutex-8 27248883 41.00 ns/op
PASS
ok command-line-arguments 1.435s
PS D:\workspaceGo go test -bench . .\src\sync\sync_mutex_test.go -cpu 16
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByMutex-16 19349876 61.73 ns/op
PASS
ok command-line-arguments 1.486s
PS D:\workspaceGo go test -bench . .\src\sync\sync_mutex_test.go -cpu 32
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByMutex-32 18658485 62.07 ns/op
PASS
ok command-line-arguments 1.490sBenchmarkReadByMutex 后面的 -2 表示 2个CPU线程同时执行总共执行了 74433837 次每个操作耗时 14.02 纳秒
我们依次执行 CPU 为 2 4 8 16 32 的情况发现对于互斥锁性能明显在下降。
二、读写锁性能测试
package mainimport (synctesting
)// 模拟临界区需要保护的数据
var cs 0// 声明读写锁
var mu sync.RWMutexfunc BenchmarkReadByRWMutex(b *testing.B) {b.RunParallel(func(p *testing.PB) {for p.Next() {mu.Lock()_ csmu.Unlock()}})
}func BenchmarkWriteByRWMutex(b *testing.B) {b.RunParallel(func(p *testing.PB) {for p.Next() {mu.Lock()csmu.Unlock()}})
}
测试结果如下
PS D:\workspaceGo go test -bench . .\src\sync\sync_rwmutex_test.go -cpu 2
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByRWMutex-2 42862144 26.88 ns/op
BenchmarkWriteByRWMutex-2 40500108 29.53 ns/op
PASS
ok command-line-arguments 4.481s
PS D:\workspaceGo go test -bench . .\src\sync\sync_rwmutex_test.go -cpu 4
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByRWMutex-4 24739767 43.13 ns/op
BenchmarkWriteByRWMutex-4 24720604 47.31 ns/op
PASS
ok command-line-arguments 2.569s
PS D:\workspaceGo go test -bench . .\src\sync\sync_rwmutex_test.go -cpu 8
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByRWMutex-8 20657990 54.24 ns/op
BenchmarkWriteByRWMutex-8 20845746 56.85 ns/op
PASS
ok command-line-arguments 2.666s
PS D:\workspaceGo go test -bench . .\src\sync\sync_rwmutex_test.go -cpu 16
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByRWMutex-16 21274909 57.08 ns/op
BenchmarkWriteByRWMutex-16 19730286 60.09 ns/op
PASS
ok command-line-arguments 3.739s
PS D:\workspaceGo go test -bench . .\src\sync\sync_rwmutex_test.go -cpu 32
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-8300H CPU 2.30GHz
BenchmarkReadByRWMutex-32 21293548 56.24 ns/op
BenchmarkWriteByRWMutex-32 18733052 60.76 ns/op
PASS
ok command-line-arguments 3.560s从测试结果中可以看出我们依旧执行了 CPU 为 2 4 8 16 32 的情况发现随着线程数的增加测试函数 BenchmarkReadByRWMutex 和测试函数 BenchmarkWriteByRWMutex 的性能并没有明细变化太大从 CPU 2 到 CPU 4 的时候比较明显但是从 CPU 4 8 16 32 性能则趋于比较平稳。
三、小结
对于互斥锁CPU 从 2 4 8 16 到 32随着并发量的增加性能从 15.35 逐步增大到 62.07 ns/op 也就是每次操作的时间在增大 对于读写锁随着并发量的增加读锁性能并未随并发量的增大而发生较大的变化始终保持在 50 左右。 通过对互斥锁sync.Mutex和 读写锁sync.RWMutex的性能测试结果对比我们得到如下结论
在并发量较小的情况下互斥锁 的性能更好但是随着并发量的逐步增大互斥锁由于锁竞争激烈导致加锁和解锁的性能下降读写锁的 读锁 性能并未锁着并发量的增大而有大的变化在并发量较大的情况下读写锁的 加锁 性能比 互斥锁、读写锁的读锁 性能都差并且随着并发量的增大写锁 性能有继续下降趋势读写锁适合在具有一定并发量且 读多写少 的场合。在大量并发下在多个 goroutine 可以同时持有读写锁的 读锁从而减少锁竞争中等待时间在大量并发下互斥锁即便是 读请求同一时刻也只能有一个 goroutine 持有锁其他 goroutine 也只能阻塞在加锁操作上等待被调度 现阶段还是对 Go 语言的学习阶段想必有一些地方考虑的不全面本文示例全部是亲自手敲代码并且执行通过。 如有问题还请指教。 评论去告诉我哦一起学习一起进步