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