首页  >  文章  >  后端开发  >  ## 如何避免并发Go程序中的死锁?

## 如何避免并发Go程序中的死锁?

Susan Sarandon
Susan Sarandon原创
2024-10-25 09:00:29677浏览

## How to Avoid Deadlocks in Concurrent Go Programs?

解决 Go 并发中的 Goroutine 死锁

在并发 Go 程序中,当 Goroutine 无限期地等待对方释放资源时,可能会出现死锁。要解决此类死锁,请考虑以下示例:

<code class="go">// Create a channel for communication between goroutines.
ch := make(chan int)

// Start producer goroutines that send values to the channel.
go producer(ch, 100*time.Millisecond, 2)
go producer(ch, 200*time.Millisecond, 5)

// Indefinite loop to continuously receive values from the channel.
for {
    fmt.Println(<-ch)
}</code>

此代码会导致死锁错误:“致命错误:所有 goroutine 都在睡眠 - 死锁!”发生这种情况是因为生产者的生命周期有限,最终会停止传输,而消费者 goroutine 则无休止地等待新值。为了避免这种僵局,可以采用两种主要策略:

1。通道终止:

由于通道只能关闭一次,因此生产者向消费者发出终止信号至关重要。协调员可以监控生产者的完成情况并相应地关闭通道。

2.协调同步:

使用像sync.WaitGroup这样的同步原语,生产者可以在完成时通知协调者,协调者可以在所有生产者完成后关闭通道。

使用同步更新代码:

<code class="go">import (
    "fmt"
    "sync"
    "time"
)

func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) {
    defer wg.Done()

    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    // Create a WaitGroup for coordinating producer completion.
    wg := &sync.WaitGroup{}

    // Initialize the channel for communication between goroutines.
    ch := make(chan int)

    // Start producer goroutines.
    wg.Add(2)
    go producer(ch, 100*time.Millisecond, 2, wg)
    go producer(ch, 200*time.Millisecond, 5, wg)

    // Assign a goroutine to close the channel when all producers have finished.
    go func() {
        wg.Wait()
        close(ch)
    }()

    // Iterate over values from the channel until it's closed.
    for v := range ch {
        fmt.Println(v)
    }
}</code>

结论:

通过实现通道终止或协调同步,开发人员可以有效避免 goroutine 死锁,确保并发 Go 程序中的适当协调。

以上是## 如何避免并发Go程序中的死锁?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn