fatal error: all goroutines are asleep - deadlock (again)
fatal error: all goroutines are asleep - deadlock (again)
我的 dicerolling 程序发生了奇怪的崩溃。它工作正常,但最后它总是说:
致命错误:所有 goroutine 都在休眠 - 死锁!
goroutine 1 [chan receive]: main.main() /tärning.go:43 +0x746
goroutine 6 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 创建者 main.main /tärning.go: 40 +0x59a
goroutine 7 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 创建者 main.main /tärning.go: 41 +0x5d3 退出状态 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()
}
我已在此处修复了您的代码:https://play.golang.org/p/ZgRRb-wOdDk 并附有评论。请检查。
您的代码中存在多个问题。
1. 你在代码中使用 wg.Add(1)
的方式是行不通的。你必须在开始你的 go 例程之前放置 wg.Add(2)
并从 dice 函数中删除 wg.Add(1)
因为可能存在比赛情况并且你的 wg.Add(1)
可以 运行 当 wg.Wait()
运行 已经。
您正在运行进行频道工作。您没有关闭任何频道。此外,运行ge 查询是一个阻塞调用。同时,您的 svaren := range svar
也将被阻止,因为没有人会向其中添加项目。所以,程序会卡在 main 函数无法从 svar
通道读取数据的情况。而且,dice
功能被卡住,因为 job
通道中没有数据,并且在 item := range job
步骤中被阻止。
因此,如果两个 go 例程相互等待,将导致死锁情况。
我的 dicerolling 程序发生了奇怪的崩溃。它工作正常,但最后它总是说:
致命错误:所有 goroutine 都在休眠 - 死锁!
goroutine 1 [chan receive]: main.main() /tärning.go:43 +0x746
goroutine 6 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 创建者 main.main /tärning.go: 40 +0x59a
goroutine 7 [chan receive]: main.dice(0xc00003a0c0, 0xc00003a120, 0xc0000100a0) /tärning.go:51 +0x106 创建者 main.main /tärning.go: 41 +0x5d3 退出状态 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()
}
我已在此处修复了您的代码:https://play.golang.org/p/ZgRRb-wOdDk 并附有评论。请检查。
您的代码中存在多个问题。
1. 你在代码中使用 wg.Add(1)
的方式是行不通的。你必须在开始你的 go 例程之前放置 wg.Add(2)
并从 dice 函数中删除 wg.Add(1)
因为可能存在比赛情况并且你的 wg.Add(1)
可以 运行 当 wg.Wait()
运行 已经。
您正在运行进行频道工作。您没有关闭任何频道。此外,运行ge 查询是一个阻塞调用。同时,您的
svaren := range svar
也将被阻止,因为没有人会向其中添加项目。所以,程序会卡在 main 函数无法从svar
通道读取数据的情况。而且,dice
功能被卡住,因为job
通道中没有数据,并且在item := range job
步骤中被阻止。因此,如果两个 go 例程相互等待,将导致死锁情况。