首頁 >後端開發 >Golang >## 如何避免並發Go程式中的死鎖?

## 如何避免並發Go程式中的死鎖?

Susan Sarandon
Susan Sarandon原創
2024-10-25 09:00:29783瀏覽

## 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