首頁 >後端開發 >Golang >如何安全地關閉 Go 中未知長度的通道?

如何安全地關閉 Go 中未知長度的通道?

Patricia Arquette
Patricia Arquette原創
2024-12-23 17:44:14486瀏覽

How to Safely Close a Channel of Unknown Length in Go?

關閉未知長度的Channel

在提供的程式碼中,出現錯誤“在關閉的通道上發送”,因為多個goroutine嘗試傳送已關閉通道上的值。這個問題是由於 Goroutine 之間缺乏同步造成的,因為一個 Goroutine 關閉了通道,而其他 Goroutine 仍在發送資料。

為了在這種情況下有效地關閉通道,必須確定所有發送者 Goroutine 何時關閉通道完成了他們的任務。這可以透過使用sync.WaitGroup來偵測所有發送者協程何時完成發送值來實現。

這是使用sync.WaitGroup的修改後的代碼:

func gen(ch chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    var i int
    for {
        time.Sleep(time.Millisecond * 10)
        ch <- i
        i++
        // when no more data (e.g. from db, or event stream)
        if i > 100 {
            break
        }
    }
}

func receiver(ch chan int) {
    for i := range ch {
        fmt.Println("received:", i)
    }
}

func main() {
    ch := make(chan int)
    wg := &sync.WaitGroup{}

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go gen(ch, wg)
    }

    go func() {
        wg.Wait()
        close(ch)
    }()

    receiver(ch)
}

在此解決方案中,每個發送者goroutine 都會向sync.WaitGroup 添加1,以指示它將在通道上發送值。 close() goroutine 中的 wg.Wait() 確保只有在所有發送者 goroutine 完成其任務後才關閉通道,從而防止「在關閉的通道上發送」錯誤。

以上是如何安全地關閉 Go 中未知長度的通道?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn