Golang 函数在并发任务中怎样使用锁

2025-01-09 03:35:13   小编

Golang 函数在并发任务中怎样使用锁

在 Golang 的并发编程场景里,多个 goroutine 同时访问和修改共享资源时,很容易引发数据竞争问题,导致程序出现难以调试的错误。而锁机制则是解决这类问题的重要手段。

首先要了解的是互斥锁(Mutex),这是最常用的一种锁。在 sync 包中,Mutex 类型提供了两个关键方法:LockUnlock。当一个 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),适用于读操作远多于写操作的场景。它允许有多个读操作同时进行,但写操作时会独占锁。RWMutexRLockRUnlock 用于读操作,LockUnlock 用于写操作。

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 函数在并发任务中安全、高效地运行,开发者需要根据实际场景选择合适的锁类型,并确保锁的正确使用。

TAGS: 锁的使用 并发任务 Golang并发 Golang函数

欢迎使用万千站长工具!

Welcome to www.zzTool.com