预期输出以及工作池中的死锁

我正在学习 Go 并发并编写了强制性工作池示例,其中有 N 个工作和 M 个工作人员(N > M)。我遇到了一个死锁 ( all goroutines are asleep),我想不通;但是,我也在死锁发生之前得到了预期的输出,这让我更加困惑。有人可以指出我做错了什么吗?


我的代码是这样的:


package main


import (

    "fmt"

    "sync"

)


// A simple worker pool implementation using channels and WaitGroups.

// Our workers simply read from a channel of integers from an input

// channel and write their squares to an output channel.


func addJobs(jobsCh chan<- int, wg *sync.WaitGroup) {

    // 100 numbers to crunch (jobs)

    for i := 1; i < 101; i++ {

        jobsCh <- i

    }

    wg.Done()

}


func worker(jobsCh <-chan int, resultsCh chan<- int, wg2 *sync.WaitGroup) {

    for num := range jobsCh {

        resultsCh <- num * num

    }

    wg2.Done()

}


func addWorkers(jobsCh <-chan int, resultsCh chan<- int, wg *sync.WaitGroup) {

    var wg2 sync.WaitGroup

    // 10 workers

    for i := 0; i < 10; i++ {

        wg2.Add(1)

        go worker(jobsCh, resultsCh, &wg2)

    }

    wg.Done()

}


func readResults(resultsCh <-chan int, wg *sync.WaitGroup) {

    for sq := range resultsCh {

        fmt.Printf("%v ", sq)

    }

    wg.Done()

}


func main() {

    var wg sync.WaitGroup

    jobsCh := make(chan int)

    resultsCh := make(chan int)


    wg.Add(1)

    go addJobs(jobsCh, &wg)


    wg.Add(1)

    go addWorkers(jobsCh, resultsCh, &wg)


    wg.Add(1)

    go readResults(resultsCh, &wg)


    wg.Wait()

}

正如预期的那样,这会打印数字的平方(以随机顺序),但也会遇到死锁。请参阅此游乐场链接。:(


沧海一幻觉
浏览 99回答 1
1回答

九州编程

关闭jobsCh导致工人退出:func addJobs(jobsCh chan<- int, wg *sync.WaitGroup) {&nbsp; &nbsp; // 100 numbers to crunch (jobs)&nbsp; &nbsp; for i := 1; i < 101; i++ {&nbsp; &nbsp; &nbsp; &nbsp; jobsCh <- i&nbsp; &nbsp; }&nbsp; &nbsp; close(jobsCh)&nbsp; // <-- add this line&nbsp; &nbsp; wg.Done()}工作人员完成后,关闭resultsCh导致结果循环退出:func addWorkers(jobsCh <-chan int, resultsCh chan<- int, wg *sync.WaitGroup) {&nbsp; &nbsp; var wg2 sync.WaitGroup&nbsp; &nbsp; // 10 workers&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg2.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go worker(jobsCh, resultsCh, &wg2)&nbsp; &nbsp; }&nbsp; &nbsp; wg2.Wait()&nbsp; &nbsp; &nbsp; &nbsp;// <-- add this line&nbsp; &nbsp; close(resultsCh) // and this line&nbsp; &nbsp; wg.Done()}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go