gpt4 book ai didi

go - fatal error : goroutines are asleep - deadlock

转载 作者:IT王子 更新时间:2023-10-29 02:15:01 46 4
gpt4 key购买 nike

努力学习并发。我遇到了以下错误:

fatal error: all goroutines are asleep - deadlock!

我被告知要添加一个 WaitGroup 和一个关闭 channel 来解决这个问题。我已经添加了这两个,但错误仍然存​​在。不确定我做错了什么。

这是我的代码 https://play.golang.org/p/ZB45oXlBUl :

package main

import (
"log"
"sync"
"time"
)

type RowInfo struct {
id int64
}

func main() {
queueChan := make(chan RowInfo)
workerChan := make(chan RowInfo)
doneChan := make(chan int64)
closeChan := make(chan struct{})

var waitGroup sync.WaitGroup

go dispatcher(queueChan, workerChan, doneChan, closeChan)

// Start WorkerCount number of workers
workerCount := 4
for i := 0; i < workerCount; i++ {
go worker(workerChan, doneChan, &waitGroup)
}

// Send test data
waitGroup.Add(12)
for i := 0; i < 12; i++ {
queueChan <- RowInfo{id: int64(i)}
}

// Prevent app close till finished execution
waitGroup.Wait()

close(closeChan)
}

func dispatcher(queueChan, workerChan chan RowInfo, doneChan chan int64, closeChan chan struct{}) {
state := make(map[int64]bool)

for {
select {
case job := <-queueChan:
if state[job.id] == true {
continue
}
workerChan <- job
case result := <-doneChan:
state[result] = false
case <-closeChan:
close(queueChan)
close(workerChan)
close(doneChan)
break
}
}
}

func worker(workerChan chan RowInfo, doneChan chan int64, waitGroup *sync.WaitGroup) {
for job := range workerChan {
time.Sleep(1 * time.Second)
log.Printf("Doing work on job rowInfo ID: %d", job.id)

// Finish job
doneChan <- job.id
waitGroup.Done()
}
}

错误:

2009/11/10 23:00:01 Doing work on job rowInfo ID: 2
2009/11/10 23:00:01 Doing work on job rowInfo ID: 0
2009/11/10 23:00:01 Doing work on job rowInfo ID: 3
2009/11/10 23:00:01 Doing work on job rowInfo ID: 1
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
/tmp/sandbox490337982/main.go:32 +0x1e0

goroutine 5 [chan send]:
main.dispatcher(0x104360c0, 0x10436100, 0x10436140, 0x10436180)
/tmp/sandbox490337982/main.go:50 +0x200
created by main.main
/tmp/sandbox490337982/main.go:21 +0x100

goroutine 6 [chan send]:
main.worker(0x10436100, 0x10436140, 0x104382e0, 0x0)
/tmp/sandbox490337982/main.go:68 +0x1a0
created by main.main
/tmp/sandbox490337982/main.go:26 +0x160

goroutine 7 [chan send]:
main.worker(0x10436100, 0x10436140, 0x104382e0, 0x0)
/tmp/sandbox490337982/main.go:68 +0x1a0
created by main.main
/tmp/sandbox490337982/main.go:26 +0x160

goroutine 8 [chan send]:
main.worker(0x10436100, 0x10436140, 0x104382e0, 0x0)
/tmp/sandbox490337982/main.go:68 +0x1a0
created by main.main
/tmp/sandbox490337982/main.go:26 +0x160

goroutine 9 [chan send]:
main.worker(0x10436100, 0x10436140, 0x104382e0, 0x0)
/tmp/sandbox490337982/main.go:68 +0x1a0
created by main.main
/tmp/sandbox490337982/main.go:26 +0x160

最佳答案

为了理解这个问题,想想 dispatcherworkers 发生了什么。

  1. 初始状态:调度员和 worker 空闲
  2. 在 queueChan 上发送:dispatcher select 发送给 workerChan
  3. worker 读取 workerChan:休眠 4 秒,写入 doneChan。
  4. 2、3重复4次,直到所有 worker 都睡了
  5. 当所有工作人员都在 sleep 时,queueChan 上有另一个工作。
  6. 调度员去做那项工作
  7. 调度程序无法在 workerChan 上发送,因为没有工作人员正在读取。
  8. 所有工作人员都熬过 sleep 并尝试发送 doneChan。

现在所有的 goroutines 都被阻塞了。

关于go - fatal error : goroutines are asleep - deadlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35351751/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com