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

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

多次運行同一個 go 程序會引發恐慌:在關閉的通道上發送

多次運行同一個 go 程序會引發恐慌:在關閉的通道上發送

Go
皈依舞 2022-06-01 16:03:45
我是 golang 的新手,并試圖了解 workerpool 的工作原理。如果我運行一次并且嘗試多次運行我會感到恐慌,則以下示例程序可以正常工作:發送關閉通道錯誤。Go 版本是 go1.14.2package mainimport (    "fmt"    "time")func main() {    jobs := make(chan int, 10)    results := make(chan int, 10)    for x := 1; x <= 3; x++ {        go worker(x, jobs, results)    }    for j := 1; j <= 6; j++ {        jobs <- j    }    close(jobs)    for r:=range results{        fmt.Println("Result received from worker: ", r)    }}func worker(ID int, jobs <-chan int, results chan<- int) {    for job := range jobs {        fmt.Println("Worker ", ID, " is working on job ", job)        time.Sleep(1000*time.Millisecond)        fmt.Println("Worker ", ID, " completed work on job ", job)        results <- job    }    close(results)}第一次運行沒問題go run main.go                                                                            Worker  3  is working on job  1Worker  1  is working on job  2Worker  2  is working on job  3Worker  2  completed work on job  3Worker  2  is working on job  4Result received from worker:  3Worker  1  completed work on job  2Worker  1  is working on job  5Result received from worker:  2Worker  3  completed work on job  1Worker  3  is working on job  6Result received from worker:  1Worker  3  completed work on job  6Result received from worker:  6第二次運行給出了這個。Worker  3  is working on job  2Worker  2  is working on job  3Worker  1  is working on job  1Worker  3  completed work on job  2Worker  3  is working on job  4Worker  2  completed work on job  3Worker  2  is working on job  5Worker  1  completed work on job  1Worker  1  is working on job  6Result received from worker:  2Result received from worker:  3Result received from worker:  1Worker  1  completed work on job  6Worker  3  completed work on job  4Result received from worker:  6panic: send on closed channel誰能幫我理解發生了什么?
查看完整描述

2 回答

?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

您有多個關閉results通道的 goroutine。


func worker(ID int, jobs <-chan int, results chan<- int) {

    for job := range jobs {

        fmt.Println("Worker ", ID, " is working on job ", job)

        time.Sleep(1000*time.Millisecond)

        fmt.Println("Worker ", ID, " completed work on job ", job)

        results <- job

    }

    close(results)            <<<<-------- Here

}

worker你在三個不同的并發 goroutine 中運行這個函數。第一個到達標記線的人關閉通道,其他人嘗試results <- job在循環中的關閉通道上發送。


查看完整回答
反對 回復 2022-06-01
?
眼眸繁星

TA貢獻1873條經驗 獲得超9個贊

Eli Bendersky 的回答描述了這個問題。這個答案描述了修復。我知道你沒有要求修復,但我假設你有興趣。所以就在這里。


修復方法是在關閉通道之前等待工作 goroutine 完成。使用sync.WaitGroup來實現等待。


var wg sync.WaitGroup

for x := 1; x <= 3; x++ {

    wg.Add(1)  // increment worker counter

    go func(x int) {

        defer wg.Done() // decrement on return from goroutine

        worker(x, jobs, results)

    }(x)

}


// Close results channel when workers are done.

go func() {

    wg.Wait()

    close(results)

}()

在 PlayGround 上運行這個 GoLANG 程序:https: //play.golang.org/p/GM-0Gqx0Gbg


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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