atomic和mutex锁使用场景问题

来源:1-9 神奇的内置数据结构

慕少9344774

2021-05-27 10:29:16

曹大,昨天在直播中提到了atomic和mutex的使用场景问题

  1. atomic和mutex分别在什么情况下用会比较好,channel用的是mutex吗?

    1. 尽量 mutex

    2. 一些比较简单的场景,比如:

      1. 配置加载双 buffer,可以用 atomic。

      2. 并发安全计数器,可以用 atomic

    3. atomic 相对来说是比较底层的 API,应用层还是尽量少用~除非在锁有明显的性能瓶颈时,需要考虑优化。

下来我测试了下

// sync.Mutex
func test1() {
var wg sync.WaitGroup
  var mutex sync.Mutex
  count := int64(0)
t := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
go func(i int) {
mutex.Lock()
count++
wg.Done()
mutex.Unlock()
}(i)
}

wg.Wait()

fmt.Printf("test1 花费时间:%d, count的值为:%d \n", time.Now().Sub(t), count)
}

// sync.atomic
func test2() {
var wg sync.WaitGroup
  count := int64(0)
t := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
go func(i int) {
atomic.AddInt64(&count, 1)
wg.Done()
}(i)
}

wg.Wait()

fmt.Printf("test2 花费时间:%d, count的值为:%d \n", time.Now().Sub(t), count)
}

执行结果:

test1 花费时间:4573742, count的值为:10000 

test2 花费时间:3195538, count的值为:10000 

结果显示atomic 的效率会高点。

为什么你建议业务层要尽量使用mutex呢?是因为atomic会对内存块直接加锁,影响系统整体的性能么?

写回答

1回答

Xargin

2021-06-23

atomic 是较底层的 api

如果用 atomic 编程需要对并发有比较深的理解,要深入地理解我们课上提了几句的内存重排,memory barrier 等相关知识

用 atomic 编写高性能数据结构还要知道使用这种 api 独有的一些并发问题,比如 ABA 问题

在深入理解这些知识的前提下,才不容易写出 bug,

同步编程这节里提到的一些数据结构就是做无锁处理的,比如 sync.Pool,你可以看看,还是比较复杂的


对于上层应用来说,atomic 太底层了~

个别计数、配置替换的场景用一用问题不大,因为逻辑比较简单


你这里的代码是很简单的计数场景,用 atomic 也没啥问题

0

Go高级工程师实战营

慕课网与 GoCN 社区官方联手打造,定义行业Go高级人才培养标准,4个月,快速晋升为P6+/D7级高级人才。

458 学习 · 266 问题

查看课程