簡體   English   中英

golang頻道死鎖問題,我應該關閉頻道嗎

[英]golang channel deadlock problems, should I close the channel

package main

import (
    "fmt"
    "sync"
)

func main(){
    ch1 := make(chan int,100)
    ct := 0
    var wg sync.WaitGroup

    wg.Add(1)
    go func(){
        //defer close(ch1)
        for i:= 0; i < 10;i ++{
            ch1 <- i
        }
    }()

    go func(){
        defer wg.Done()
        for x := range ch1{
            fmt.Println(x)
        }
    }()
    wg.Wait()

    fmt.Println("numbers:",ct)
}

為什么這段代碼會返回fatal error: all goroutines are asleep - deadlock! 我發現如果我關閉頻道就不會出現死鎖,但我不知道為什么會這樣。 將所有項目輸入頻道后是否必須關閉頻道?

僅當/當通道關閉時,通道上for range才會終止。 如果你不關閉通道並且不發送更多的值, for range語句將永遠阻塞, wg.Wait()main goroutine 也會阻塞。

一旦發送所有值,“發送方”方應關閉通道,向“接收方”方發出信號,表示通道上不會再有任何值。

所以是的,你應該關閉頻道:

go func() {
    defer close(ch1)
    for i := 0; i < 10; i++ {
        ch1 <- i
    }
}()

除非您關閉通道,否則從通道讀取的 for 循環將繼續讀取。 這就是死鎖的原因,因為從通道讀取的 goroutine 是唯一活動的 goroutine,沒有其他 goroutine 可以寫入。 當您關閉時,for 循環終止。

  1. 范圍未關閉的 ch1 將導致阻塞;
  2. 即使關閉 ch1,仍然可以從 ch1 接收數據;
  3. 可以說,close(ch1)會向ch1發送一個特殊的消息,可以用來通知ch1的接收者不會再收到數據了。 所以即使ch1里有數據,也可以close(),而不會導致接收方收不到剩余的數據。
  4. 通道不需要通過close來釋放資源。 只要沒有 goroutine 持有通道,相關資源就會自動釋放。 取消注釋 defer close(ch1) 將解決這個問題。 這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM