首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试go信道吞吐量-所有goroutines死锁

测试go信道吞吐量-所有goroutines死锁
EN

Stack Overflow用户
提问于 2014-01-08 21:47:16
回答 2查看 275关注 0票数 1

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

代码语言:javascript
复制
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
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-08 23:22:14

您的代码go func(i int) { anItem := <-workQueue[i]; ... }workQueue[i]中删除了仅1项,但是您正在尝试将WORK_PER_WORKER项填充到其中。您将处理多个项的并发性,在此之后,所有的阅读对象都已终止,并且您将陷入死锁。

在员工大猩猩中循环“解决”了您的死锁:http://play.golang.org/p/j2pavqnBDv只是“解决”了,因为这些员工大猩猩永远不会终止。也许你可以尝试在你的频道上使用close来通知工作人员什么时候什么都不会发送。

票数 2
EN

Stack Overflow用户

发布于 2014-01-08 23:22:04

因为您的员工只处理一个任务,然后退出。因此,只有第一个CONCURRENCY项继续进行,然后workQueue[i/WORK_PER_WORKER] <- workToDo有限地阻塞。因此,completed chan永远得不到足够的值,main也永远阻塞。

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

代码语言:javascript
复制
for i := 0; i < CONCURRENCY; i++ {
    go func(i int) {
        for anItem := range workQueue[i] {
            work()
            anItem.Done <- 1
        }
    }(i)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21007259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档