go锁与chan的性能对比

锁的作用

  • 解决并发安全问题,流程控制等

chan 的作用

  • 线程通信(数据传输), 并发安全,流程控制

golang的数据并不是并发安全的

  • golang的变量并不是并发安全的
  • 锁与chan都可以解决并发安全的问题,那么应该如何选择?
go 复制代码
// 锁
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
相关推荐
猷咪6 分钟前
C++基础
开发语言·c++
IT·小灰灰7 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧9 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q9 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳09 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾9 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683613 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计27 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673739 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗41 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl