Concurrency 所有go例程都处于休眠状态-死锁

Concurrency 所有go例程都处于休眠状态-死锁,concurrency,go,Concurrency,Go,我正在使用Go构建工作系统的框架,我得到了“致命错误:所有goroutines都处于休眠状态-死锁!” 我使用两个渠道进行协调,一个是创造就业机会,另一个是发送结果。创建作业后,我关闭输入通道 我的问题是如何关闭输出通道,以便程序能够正确退出。 代码是: package main import ( "bufio" "flag" "fmt" "log" "math/rand" "os" "time" ) type Work struct

我正在使用Go构建工作系统的框架,我得到了“致命错误:所有goroutines都处于休眠状态-死锁!”

我使用两个渠道进行协调,一个是创造就业机会,另一个是发送结果。创建作业后,我关闭输入通道

我的问题是如何关闭输出通道,以便程序能够正确退出。 代码是:

package main

import (
    "bufio"
    "flag"
    "fmt"
    "log"
    "math/rand"
    "os"
    "time"
)

type Work struct {
    id int
    ts time.Duration
}

const (
    NumWorkers = 5000
    NumJobs    = 100000
)

func worker(in <-chan *Work, out chan<- *Work) {
    for w := range in {
        st := time.Now()
        time.Sleep(time.Duration(rand.Int63n(int64(200 * time.Millisecond))))
        w.ts = time.Since(st)
        out <- w
    }
}

func main() {
    wait := flag.Bool("w", false, "wait for <enter> before starting")
    flag.Parse()

    if *wait {
        fmt.Printf("I'm <%d>, press <enter> to continue", os.Getpid())
        reader := bufio.NewReader(os.Stdin)
        reader.ReadString('\n')
    }

    Run()
}

func Run() {
    in, out := make(chan *Work, 100), make(chan *Work, 100)
    for i := 0; i < NumWorkers; i++ {
        go worker(in, out)
    }
    go createJobs(in)
    receiveResults(out)
}

func createJobs(queue chan<- *Work) {
    for i := 0; i < NumJobs; i++ {
        work := &Work{i, 0}
        queue <- work
    }
    close(queue)
}

func receiveResults(completed <-chan *Work) {
    for w := range completed {
        log.Printf("job %d completed in %s", w.id, w.ts)
    }
}
主程序包
进口(
“布菲奥”
“旗帜”
“fmt”
“日志”
“数学/兰德”
“操作系统”
“时间”
)
类型工作结构{
id int
ts时间。持续时间
}
常数(
NumWorkers=5000
NumJobs=100000
)

func-worker(in我错过了原始答案中关于你知道死锁原因的部分

  • 你提到了WaitGroup,它基本上只是一个信号量
  • 你可以使用另一个“控制”频道,当工人们完成任务时,他们会打开这个频道
-


但是这个频道永远不会关闭

有很多信息被打印出来(gorutines的状态)这有助于诊断此类问题纠正。我正在考虑使用WaitGroup关闭已完成的频道,因为我不想用其他方式来关闭它。我错过了您描述中的最后一句话。这是一个可能的解决方案。Arjan,我正在使用您建议的控制频道,非常感谢:)我用最终代码创建了一个要点:
func worker(ctrl chan<- bool, in <-chan *Work, out chan<- *Work) {
    for w := range in {
        st := time.Now()
        time.Sleep(time.Duration(rand.Int63n(int64(200 * time.Millisecond))))
        w.ts = time.Since(st)
        out <- w
    }
    ctrl <- true
}

func control(ctrl <-chan bool, numWorkers int, out chan<- *Work) {
    for i=0; i<numWorkers; i++ {
        <-ctrl
    }
    close(out)
}
for w := range completed {
    log.Printf("job %d completed in %s", w.id, w.ts)
}