为了账号安全,请及时绑定邮箱和手机立即绑定

致命错误:所有 goroutine 都处于休眠状态 - 死锁(再次)

致命错误:所有 goroutine 都处于休眠状态 - 死锁(再次)

Go
HUH函数 2022-06-01 17:53:54
我的 dicerolling 程序发生了一次奇怪的崩溃。它工作正常,但最后它总是说:致命错误:所有 goroutine 都处于休眠状态 - 死锁!goroutine 1 [chan 接收]: main.main() /tärning.go:43 +0x746goroutine 6 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 created by main.main /tärning.go:40 +0x59agoroutine 7 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 created by main.main /tärning.go:41 +0x5d3 exit status 2package mainimport (    "fmt"    "sync"    "math/rand")type tärning struct {    rubrik string    minTal, maxTal int}type tärningsSvar struct {    rubrik string    svaret int}func main() {    var wg sync.WaitGroup    fmt.Println("Dags att kasta tärningar")    var antal int    fmt.Println("Hur många tärningar vill du använda?")    fmt.Scan(&antal)    job := make(chan tärning, antal)    svar := make(chan tärningsSvar, antal)    for i := 0; i < antal; i++ {        fmt.Println("Vad ska tärning", i+1, "ha för rubrik?")        var text string        fmt.Scan(&text)        fmt.Println("Vad ska vara minsta värdet på tärningen?")        var minsta int        fmt.Scan(&minsta)        fmt.Println("Vad ska vara största värdet på tärningen?")        var största int        fmt.Scan(&största)        job <- tärning{rubrik: text, minTal: minsta, maxTal: största}    }    go dice(job, svar, &wg)    go dice(job, svar, &wg)    wg.Wait()    for svaren := range svar {        fmt.Println("Tärning " + svaren.rubrik + " fick: ", svaren.svaret)    }}func dice(job chan tärning, svar chan tärningsSvar, wg *sync.WaitGroup) {    wg.Add(1)     for item := range job {        text := item.rubrik        min := item.minTal        max := item.maxTal        slump := (rand.Intn(max - min) + min)        svar <- tärningsSvar{rubrik: text, svaret: slump}    }    wg.Done()}
查看完整描述

1 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

我已在此处修复了您的代码:https: //play.golang.org/p/ZgRRb-wOdDk并附有评论。请检查。

您的代码中有多个问题。1.你 wg.Add(1)在代码中使用的方式,它不起作用。你必须wg.Add(2) 在开始你的 goroutine 之前放置并删除wg.Add(1)from dice 功能,因为可能会出现比赛情况并且你wg.Add(1)可以在已经运行时wg.Wait()运行。

  1. 您正在从事频道工作。您没有关闭任何频道。此外,范围查询是一个阻塞调用。同时,您svaren := range svar也将被阻止,因为没有人会向其中添加项目。因此,程序将陷入主函数被阻止从svar通道读取数据的情况。而且,dice功能卡住了,因为通道中没有数据job并且它被item := range job一步阻塞。

  2. 因此,如果两个 goroutine 相互等待,则会导致死锁情况。


查看完整回答
反对 回复 2022-06-01
  • 1 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信