发布时间:2024-11-05 19:05:19
在Golang中,可以使用sync包提供的Mutex类型来实现互斥锁。下面是一个示例:
import (
"sync"
"fmt"
)
func main() {
var mu sync.Mutex
var data int
go func() {
mu.Lock() // 获取互斥锁
data = 5 // 修改共享资源
mu.Unlock() // 释放互斥锁
}()
mu.Lock() // 获取互斥锁
fmt.Println(data)
mu.Unlock() // 释放互斥锁
}
上述示例中,我们使用了互斥锁来保护共享资源`data`的访问。首先,我们创建了一个互斥锁`mu`。然后,在新的goroutine中,我们通过调用`mu.Lock()`来获取互斥锁。一旦获取到互斥锁,我们可以修改共享资源`data`,并在完成操作后调用`mu.Unlock()`来释放互斥锁。在主函数中,我们也使用同样的方式来获取和释放互斥锁,并打印共享资源`data`的值。
互斥锁的工作原理很简单:当一个goroutine获取到互斥锁后,其他试图获取同样互斥锁的goroutine将被阻塞,直到该互斥锁被释放。
在Golang中,互斥锁具有公平性,即先到先得。这意味着获取互斥锁的goroutine排队等待的顺序取决于它们调用`Lock()`的顺序。这种公平性保证了互斥锁的正确性。
需要注意的是,互斥锁只能由持有者进行解锁。如果尝试解锁一个未加锁的互斥锁,将会导致运行时恐慌。因此,编写正确的多线程代码时一定要小心处理互斥锁。
import (
"sync"
"fmt"
)
func main() {
var mu sync.Mutex
var data int
for i := 0; i < 10; i++ {
go func(i int) {
mu.Lock() // 获取互斥锁
data = i // 修改共享资源
mu.Unlock() // 释放互斥锁
}(i)
}
mu.Lock() // 获取互斥锁
fmt.Println(data)
mu.Unlock() // 释放互斥锁
}
在上述示例中,我们创建了10个goroutine来对共享变量`data`进行赋值操作。由于我们使用了互斥锁,每次只有一个goroutine能够获得互斥锁并对共享变量进行修改。这样,我们就保证了赋值操作的正确性。
参考文献: