Go并发编程中sync.Mutex锁失效原因及解决方案
在Go并发编程中,sync.Mutex常用于保护共享资源,确保数据一致性。本文分析一个使用sync.Mutex和sync.WaitGroup但结果不符合预期的例子,并探讨其原因和解决方法。
问题:代码意图是使用1000个协程对变量a进行1000次加1操作,预期结果a为1000。但实际运行结果却随机,这是因为sync.Mutex使用错误。
原因:原代码中,每个协程都创建了一个独立的sync.Mutex实例:var locker sync.Mutex。这意味着每个协程拥有自己的锁,互不干扰,导致多个协程同时修改a,结果不准确。
解决方案:
方法一:将var locker sync.Mutex声明移到for循环外部。这样,所有协程共享同一个sync.Mutex实例,保证同一时刻只有一个协程访问和修改a。修改后的代码如下:
package main import ( "fmt" "sync" ) func main() { var a = 0 var wg sync.WaitGroup var locker sync.Mutex // 将锁声明移至此处 for i := 0; i < 1000; i++ { wg.Add(1) go func(i int) { defer wg.Done() locker.Lock() // 使用共享锁 a++ locker.Unlock() }(i) } wg.Wait() fmt.Println("a =", a) // 输出 a = 1000 }
方法二:使用Go提供的原子操作函数atomic.AddInt64()。该函数保证对64位整数的原子操作,无需锁即可实现线程安全,效率更高。
通过以上两种方法,可以有效解决sync.Mutex锁失效问题,确保最终结果为1000。 选择方法二(原子操作)通常是更优的方案,因为它避免了锁的开销,在高并发场景下性能更好。
以上就是Go并发编程中sync.Mutex锁失效的原因是什么?的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号