技术文摘
Golang 函数在并发任务中怎样使用锁
2025-01-09 03:35:13 小编
Golang 函数在并发任务中怎样使用锁
在 Golang 的并发编程场景里,多个 goroutine 同时访问和修改共享资源时,很容易引发数据竞争问题,导致程序出现难以调试的错误。而锁机制则是解决这类问题的重要手段。
首先要了解的是互斥锁(Mutex),这是最常用的一种锁。在 sync 包中,Mutex 类型提供了两个关键方法:Lock 和 Unlock。当一个 goroutine 调用 Lock 方法时,它会获取锁,如果此时锁已经被其他 goroutine 持有,那么这个 goroutine 会被阻塞,直到锁被释放。当操作完成后,必须调用 Unlock 方法来释放锁,以便其他 goroutine 可以获取。
package main
import (
"fmt"
"sync"
)
var (
count int
mu sync.Mutex
)
func increment(wg *sync.WaitGroup) {
defer wg.Done()
mu.Lock()
count++
mu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final count:", count)
}
在这段代码中,多个 goroutine 尝试对 count 进行递增操作。通过 mu.Lock() 和 mu.Unlock() 确保了同一时间只有一个 goroutine 能修改 count,避免了数据竞争。
还有读写锁(RWMutex),适用于读操作远多于写操作的场景。它允许有多个读操作同时进行,但写操作时会独占锁。RWMutex 有 RLock、RUnlock 用于读操作,Lock、Unlock 用于写操作。
package main
import (
"fmt"
"sync"
)
var (
data int
rwmu sync.RWMutex
)
func read(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.RLock()
fmt.Println("Read data:", data)
rwmu.RUnlock()
}
func write(wg *sync.WaitGroup, value int) {
defer wg.Done()
rwmu.Lock()
data = value
fmt.Println("Write data:", data)
rwmu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go read(&wg)
}
wg.Add(1)
go write(&wg, 100)
wg.Wait()
}
在这个例子中,读操作可以并发执行,提高了程序性能,而写操作时会独占锁,保证数据一致性。
合理使用锁机制,能让 Golang 函数在并发任务中安全、高效地运行,开发者需要根据实际场景选择合适的锁类型,并确保锁的正确使用。
- 手把手指导 Mofish 库(摸鱼库)的打包发布
- CSS Opacity(透明度)全解析:一篇文章带你知晓
- Starship 助力定制 shell 提示符
- 1.5 万 Star!程序员的网络瑞士军刀
- 深入探究 Go GC 之 eBPF 路径
- ULID 和 UUID:JavaScript 中可排序随机 ID 生成器
- Python 的 f-strings 功能超乎想象
- 拼刀刀店铺后台参数 Anti-content 的逆向剖析
- Java 学习中的最大难点及克服之道
- Ingress-Nginx 助力应用灰度发布的方法
- SpringBoot 中全链路调用日志跟踪的优雅实现方法
- JDK、JRE 与 JVM 的区别,让我为你揭晓
- Java那些事:易混淆概念之 OpenJDK 与 oracleJDK、Java EE 与 Jakarta EE
- 在嵌入式系统中添加音频编解码器的五个技巧
- 前端设计模式系列之外观(门面)模式