[go 面试] 为并发加锁:保障数据一致性(分布式锁)

关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

在单机程序中,当多个线程或协程同时修改全局变量时,为了保障数据一致性,我们需要引入锁机制,创建临界区。本文将通过一个简单的例子,说明在不加锁的情况下并发计数可能导致的问题,并介绍加锁的解决方案。

不加锁的并发计数

package main

import (
	"sync"
)

// 全局变量
var counter int

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			counter++
		}()
	}

	wg.Wait()
	println(counter)
}


运行多次得到不同的结果:

❯❯❯ go run local_lock.go
945
❯❯❯ go run local_lock.go
937
❯❯❯ go run local_lock.go
959


这是因为多个 goroutine 同时对 counter 进行修改,由于不加锁,存在竞争条件,导致最终的结果不确定。

引入互斥锁解决竞争条件

package main

import (
	"sync"
)

var counter int
var mu sync.Mutex // 互斥锁

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			mu.Lock() // 加锁
			counter++
			mu.Unlock() // 解锁
		}()
	}

	wg.Wait()
	println(counter)
}


通过引入互斥锁 sync.Mutex,在对 counter 进行修改前加锁,修改

你可能感兴趣的:(Golang,golang,面试,分布式)