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

我的 dicerolling 程序发生了一次奇怪的崩溃。它工作正常,但最后它总是说:


致命错误:所有 goroutine 都处于休眠状态 - 死锁!


goroutine 1 [chan 接收]: main.main() /tärning.go:43 +0x746


goroutine 6 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 created by main.main /tärning.go:40 +0x59a


goroutine 7 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 created by main.main /tärning.go:41 +0x5d3 exit status 2


package main


import (

    "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()

}


HUH函数
浏览 115回答 1
1回答

呼如林

我已在此处修复了您的代码:https:&nbsp;//play.golang.org/p/ZgRRb-wOdDk并附有评论。请检查。您的代码中有多个问题。1.你&nbsp;wg.Add(1)在代码中使用的方式,它不起作用。你必须wg.Add(2)&nbsp;在开始你的 goroutine 之前放置并删除wg.Add(1)from dice 功能,因为可能会出现比赛情况并且你wg.Add(1)可以在已经运行时wg.Wait()运行。您正在从事频道工作。您没有关闭任何频道。此外,范围查询是一个阻塞调用。同时,您svaren := range svar也将被阻止,因为没有人会向其中添加项目。因此,程序将陷入主函数被阻止从svar通道读取数据的情况。而且,dice功能卡住了,因为通道中没有数据job并且它被item := range job一步阻塞。因此,如果两个 goroutine 相互等待,则会导致死锁情况。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go