测试 go channel 吞吐量 - 所有 goroutine 死锁

我做了一个小程序来对 go channel 吞吐量进行基准测试,但是它总是死锁,我很努力地尝试但不明白为什么:


package main


import (

    "fmt"

    "runtime"

)


const CONCURRENCY = 32

const WORK_PER_WORKER = 100

const TOTAL_WORK = CONCURRENCY * WORK_PER_WORKER


func work() {

    sum := 0

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

        sum *= i

    }

}


type WorkItem struct {

    Done chan int

}


func main() {

    runtime.GOMAXPROCS(CONCURRENCY)

    var workQueue [CONCURRENCY]chan *WorkItem

    // initialize workers

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

        workQueue[i] = make(chan *WorkItem)

    }

    // start workers

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

        go func(i int) {

            anItem := <-workQueue[i]

            work()

            anItem.Done <- 1

        }(i)

    }

    completed := make(chan bool, TOTAL_WORK)

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

        go func(i int) {

            // send work to queues

            workToDo := &WorkItem{Done: make(chan int)}

            workQueue[i/WORK_PER_WORKER] <- workToDo // !! DEADLOCK

            // wait until the work is done

            <-workToDo.Done

            completed <- true

        }(i)

    }

    fmt.Println("Waiting")

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

        <-completed

    }

}


慕慕森
浏览 261回答 2
2回答

隔江千里

因为你的工人只处理一项任务然后退出。因此,只有第一个CONCURRENCY项目继续进行,然后workQueue[i/WORK_PER_WORKER] <- workToDo无限地阻塞。因此,completedchan 永远不会收到足够的值并且main永远阻塞。您的工作人员应该在循环中工作,如下所示:for i := 0; i < CONCURRENCY; i++ {&nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; for anItem := range workQueue[i] {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; work()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; anItem.Done <- 1&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }(i)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go