深入Go语言互斥锁的并发行为
本文分析Go语言sync.Mutex互斥锁的并发行为,重点探讨外层锁对内层锁获取的影响。以下代码片段展示了一个常见的场景:
package main import ( "fmt" "sync" "time" ) func main() { var mutex sync.Mutex wait := sync.WaitGroup{} fmt.Println("Locked") mutex.Lock() // 外层锁 for i := 1; i <= 3; i++ { wait.Add(1) go func(i int) { defer wait.Done() fmt.Printf("Not locked: %d\n", i) mutex.Lock() fmt.Printf("Locked: %d\n", i) time.Sleep(100 * time.Millisecond) mutex.Unlock() fmt.Printf("Unlocked: %d\n", i) }(i) } fmt.Println("Unlocked") mutex.Unlock() // 释放外层锁 wait.Wait() }
这段代码中,主goroutine先获取mutex锁,然后启动三个goroutine,每个goroutine都尝试获取同一个锁。 很多人误以为外层锁会完全阻止内层锁的获取。
然而,实际运行结果并非如此:
立即学习“go语言免费学习笔记(深入)”;
Locked Not locked: 1 Not locked: 2 Not locked: 3 Unlocked Locked: 1 Unlocked: 1 Locked: 2 Unlocked: 2 Locked: 3 Unlocked: 3
结果表明,三个goroutine在尝试获取锁(mutex.Lock())之前,已经执行了fmt.Printf("Not locked: %d\n", i)语句。 Unlocked的打印位置也证实了这一点:它在所有goroutine尝试获取锁但尚未成功之前打印。 之后,goroutine才依次获取锁,执行后续代码,并最终释放锁。
因此,外层锁并非没有影响内层锁,而是Go语言的并发调度机制导致goroutine在尝试获取锁前已执行部分代码。 外层锁的持有阻止了goroutine立即获取内层锁,但并不阻止goroutine执行其他代码。 只有在外层锁释放后,等待的goroutine才能依次获得锁。
以上就是Go语言互斥锁:外层锁是否会影响内层锁的获取?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号