【问题标题】:Testing go channel throughput - all goroutines deadlock测试 go 通道吞吐量 - 所有 goroutines 死锁
【发布时间】:2014-01-08 21:47:16
【问题描述】:

我做了一个小程序来测试go通道吞吐量,但是它总是死锁,我很努力但不明白为什么:

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
    }
}

【问题讨论】:

    标签: concurrency go deadlock goroutine


    【解决方案1】:

    您的代码 go func(i int) { anItem := &lt;-workQueue[i]; ... } 仅从 workQueue[i] 中删除了 1 项,但您正试图将 WORK_PER_WORKER 项填入其中。您将在 CONCURRENCY 上处理许多项目,然后所有读取 goroutine 都已终止,并且您遇到了死锁。

    在工作 goroutines 中循环“解决”你的死锁:http://play.golang.org/p/j2pavqnBDv 只是“解决”,因为这些工作 goroutine 永远不会终止。也许您可以尝试closeing 您的频道,以便在没有发送任何内容时通知工作人员 goroutine。

    【讨论】:

      【解决方案2】:

      因为您的工作人员只处理一项任务然后退出。因此,只有第一个 CONCURRENCY 项目继续,然后 workQueue[i/WORK_PER_WORKER] &lt;- workToDo 无限阻塞。因此,completed chan 永远不会收到足够的值,main 也会永远阻塞。

      您的工作人员应该循环工作,如下所示:

      for i := 0; i < CONCURRENCY; i++ {
          go func(i int) {
              for anItem := range workQueue[i] {
                  work()
                  anItem.Done <- 1
              }
          }(i)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-24
        • 2018-02-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多