Golang并发锁使用详解
什么是并发锁
在 Go 语言中,关于并发锁的讨论,并不仅限于第三方库,而是深入在编程语言的核心API 规范里的。Go语言提供了有助于编码并发应用的丰富API,而这些API中锁的使用无疑是其中重要组成部分。说起锁,就不得不提到 Race Condition(竞争条件) 了。在竞争条件的情况下,Go程序会发生不可预期和不稳定的行为,为了避免这种情况,需要使用锁机制,让程序保持稳定,不互斥,不冲突。
互斥锁mutex
在 Go 语言中,sync.Mutex 即是互斥锁。 其中 Mutex 是一个互斥锁结构体,包含两个重要方法:Lock 和 Unlock,Lock 方法用于获取锁,Unlock 用于释放锁。互斥锁可以保证在同一时间只有一个 goroutine 可以执行临界区代码,其他 goroutine 都在等待获取锁,当临界区代码执行完成后,再释放锁,其他 goroutine 才能获取锁,进入临界区执行代码。
示例代码如下:
package main
import (
"fmt"
"sync"
)
type counter struct {
i int64
sync.Mutex
}
func (c *counter) increment() {
c.Lock()
defer c.Unlock() //defer 在函数结束时解锁
c.i += 1
fmt.Println("Increment done")
}
func (c *counter) decrement() {
c.Lock()
defer c.Unlock() //defer 在函数结束时解锁
c.i -= 1
fmt.Println("Decrement done")
}
func (c *counter) value() int64 {
return c.i
}
func main() {
c := counter{i: 0}
var wg sync.WaitGroup
for i := 0; i < 10000; i++ {
wg.Add(1)
go func() {
c.increment()
wg.Done()
}()
}
wg.Wait()
fmt.Println("Final value:", c.value())
}
读写锁RWMutex
读写锁(RWMutex)比互斥锁(Mutex)稍微复杂一些,但它适用于场合,其中读操作远远超过写操作,这时读写锁使用比互斥锁效率更高,因为可以同时多个执行读操作,但同一时间只能有一个 goroutine 执行写操作
在 Go 语言中,sync.RWMutex即是读写锁。 其中 RWMutex 也有两个重要方法:RLock 和 RUnlock,用于获取和释放读锁,Lock 和 Unlock 则是获取和释放写锁。
示例代码如下:
package main
import (
"fmt"
"sync"
)
type counter struct {
i int64
sync.RWMutex
}
func (c *counter) increment() {
c.Lock()
defer c.Unlock()
c.i += 1
fmt.Println("Increment done")
}
func (c *counter) decrement() {
c.Lock()
defer c.Unlock()
c.i -= 1
fmt.Println("Decrement done")
}
func (c *counter) value() int64 {
c.RLock()
defer c.RUnlock()
return c.i
}
func main() {
c := counter{i: 0}
var wg sync.WaitGroup
for i := 0; i < 10000; i++ {
switch {
case i%2 == 0:
wg.Add(1)
go func() {
c.increment()
wg.Done()
}()
case i%2 == 1:
wg.Add(1)
go func() {
c.decrement()
wg.Done()
}()
}
}
wg.Wait()
fmt.Println("Final value:", c.value())
}
在示例代码中,利用读写锁,c.increment(), c.decrement()方法中使用写锁来更新计数器 c.i 的值,而在 c.value() 方法中,使用读锁来读取计数器的值,这样可以更好地利用goroutine的并发特性,同时提升了程序的效率。
结论
在并发编程中,锁的使用相当重要,可以更好地避免竞争条件,保证并发执行的正确性。Go语言提供了互斥锁和读写锁,是并发编程中的重要API,需要在实际应用中灵活运用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang并发锁使用详解 - Python技术站