- 锁的作用
- chan 的作用
- golang的数据并不是并发安全的
- 为什么锁的性能更加优秀?
- 如何选择?
锁的作用
- 解决并发安全问题,流程控制等
chan 的作用
- 线程通信(数据传输), 并发安全,流程控制
golang的数据并不是并发安全的
- golang的变量并不是并发安全的
- 锁与chan都可以解决并发安全的问题,那么应该如何选择?
// 锁
func LockServe(lock *sync.Mutex) {lock.Lock()defer lock.Unlock()//todo: 业务逻辑//...
}// channel 读(单线程)
func ChanRead(ch chan struct{}) {for {<-ch}
}// channel 读(多线程)
func ChanReadMulti(ch chan struct{}) {for i := 0; i < 100; i++ {go ChanRead(ch)}
}// channel 写
func ChanWrite(ch chan struct{}) {ch <- struct{}{}
}// 读写锁性能(单线程)
func BenchmarkLock(b *testing.B) {lock := &sync.Mutex{}//开始计时b.ResetTimer()for i := 0; i < b.N; i++ {LockServe(lock)}//BenchmarkLock-8 128537480 9.141 ns/op 0 B/op
}// 读写锁性能(多线程)
func BenchmarkLockMulti(b *testing.B) {lock := &sync.Mutex{}//开始计时b.ResetTimer()b.RunParallel(func(pb *testing.PB) {for pb.Next() {LockServe(lock)}})//BenchmarkLockMulti-8 15528596 77.23 ns/op 0 B/op
}// channel 通信(单线程)
func BenchmarkChanRead(b *testing.B) {ch := make(chan struct{}, 9)defer close(ch)go ChanRead(ch)//开始计时b.ResetTimer()for i := 0; i < b.N; i++ {ChanWrite(ch)}//BenchmarkChanRead-8 21222759 55.43 ns/op 0 B/op
}// channel 通信(多线程读)
func BenchmarkChanReadMulti(b *testing.B) {ch := make(chan struct{}, 9)defer close(ch)go ChanReadMulti(ch)//开始计时b.ResetTimer()for i := 0; i < b.N; i++ {ChanWrite(ch)}//BenchmarkChanReadMulti-8 4238251 260.1 ns/op 0
}// channel 通信(多线程写)
func BenchmarkChanWrite(b *testing.B) {ch := make(chan struct{}, 1000)defer close(ch)go ChanRead(ch)//开始计时b.ResetTimer()b.RunParallel(func(pb *testing.PB) {for pb.Next() {ChanWrite(ch)}})// BenchmarkChanWrite-8 5177377 299.1 ns/op 0 B/op
}// channel 通信(多线程读写)
func BenchmarkChanReadWrite(b *testing.B) {ch := make(chan struct{}, 1000)defer close(ch)go ChanReadMulti(ch)//开始计时b.ResetTimer()b.RunParallel(func(pb *testing.PB) {for pb.Next() {ChanWrite(ch)}})// BenchmarkChanReadWrite-8 558490 3862 ns/op 0 B/op 0 allocs/op
}
在单线程下:锁 :128537480 qps; chan: 21222759 qps
多线程下: 锁 : 15528596 qps; chan : 5177377 qps
单论性能,锁要比chan更加优秀
为什么锁的性能更加优秀?
- 锁是原子的操作,消耗更低,性能更高
- chan的底层有更加复杂的通信逻辑,消耗较大,在多线程情况下相差3倍
如何选择?
- 在之需要解决并发问题或者流程控制的情况下优先考虑锁,因为性能更高
- 如果需要线程通信 以及 数据传输使用chan