亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

一個通道有一個接收者和未知數量的 goroutines 發送者導致死鎖

一個通道有一個接收者和未知數量的 goroutines 發送者導致死鎖

Go
慕俠2389804 2023-06-01 14:59:13
我有一個頻道,接收器是主要的。我生成了多個 goroutine,每個 goroutine 通過通道發送一個字符串?,F在,這會導致死鎖,因為我沒有使用 close 函數正確關閉通道。問題是,我不知道將創建多少 goroutines,因此無法知道何時關閉通道。我試過使用 WaitGroup,問題是,我讀到我不能在 goroutine 中使用 Add,我應該在主進程/goroutine 中使用 wg.Add(1),我試過使用 Add in父 goroutine 產生子 goroutine,這也導致了死鎖包主import (    "fmt"    "sync")var i = 0func doSomething(ch chan string, wg sync.WaitGroup) {    defer wg.Done()    ch <- fmt.Sprintf("doSomething: %d", i)    i++    if i == 10 {return}    wg.Add(1)    go doSomething(ch, wg)}func main() {    ch := make(chan string)    var wg sync.WaitGroup    wg.Add(1)    go doSomething(ch, wg)    wg.Wait()    for s := range ch {        fmt.Println(s)    }}現在,這只是一個測試代碼,所以,假設我們不知道我們將只創建 10 個 goroutines,假設它在運行時是未知的,如果我不使用,我會立即得到一個沒有任何輸出的死鎖錯誤WorkGroup 我在打印第 10 個字符串之前收到錯誤(因為我沒有關閉通道)我還嘗試過不為每個函數調用生成一個 goroutine,而是對所有遞歸調用(從 main 開始)使用一個 goroutine,并關閉通道,我為 go 創建了一個匿名函數,它首先調用 doSomething 函數然后調用關閉,所以所有的遞歸調用都會被評估,我們肯定知道什么時候關閉通道。但是,這就是我現在想要完成的,我試圖讓未知數量的 goroutine 一起工作,并在它們以某種方式完成后關閉通道。
查看完整描述

1 回答

?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

有幾個問題。


第一個是程序在將它們作為參數傳遞時復制等待組值。復制時等待組不能正常工作。而是將指針傳遞給等待組。


第二個問題是 main 在從通道接收值之前等待所有 goroutines 完成。因為通道的緩沖區不夠大,無法容納所有發送的值,所以程序會死鎖。


第三個問題是通道上方的主要范圍,但沒有任何東西關閉通道。Main 不會因此退出。


要解決第二個和第三個問題,請啟動另一個 goroutine 等待doSomthings 并在完成后關閉通道。


嘗試這個:


func doSomething(ch chan string, wg *sync.WaitGroup) {

    defer wg.Done()

    ch <- fmt.Sprintf("doSomething: %d", i)

    i++

    if i == 10 {

        return

    }

    wg.Add(1)

    go doSomething(ch, wg)

}


func main() {

    ch := make(chan string)

    var wg sync.WaitGroup

    wg.Add(1)

    go doSomething(ch, &wg)

    go func() {

        wg.Wait()

        close(ch)

    }()

    for s := range ch {

        fmt.Println(s)

    }

}


查看完整回答
反對 回復 2023-06-01
  • 1 回答
  • 0 關注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號