英文:
Unable to find reason for go deadlock
问题
无法找到代码死锁的原因。这里的目标是在收到信号后,使工作协程执行一些工作。
如果从代码中移除signalStream通道,它可以正常工作。但是当引入该通道时,它会发生死锁。不确定原因。如果有任何工具可以解释死锁的发生,那将会有所帮助。
package main
import (
"log"
"sync"
)
const jobs = 10
const workers = 5
var wg sync.WaitGroup
func main() {
// 创建通道
dataStream := make(chan interface{})
signalStream := make(chan interface{})
// 生成工作协程
for i := 1; i <= workers; i++ {
wg.Add(1)
go worker(dataStream, signalStream, i*100)
}
// 生成任务
for i := 1; i <= jobs; i++ {
dataStream <- i
}
close(dataStream)
// 开始消费数据
close(signalStream)
wg.Wait()
}
func worker(c <-chan interface{}, s <-chan interface{}, id int) {
defer wg.Done()
<-s
for i := range c {
log.Printf("routine - %d - %d \n", id, i)
}
}
英文:
Unable to find a reason as to why this code deadlocks. The aim here is make the worker go routines do some work only after they are signaled.
If the signalStream channel is removed from the code, it works fine. But when this is introduced, it deadlocks. Not sure the reason for this. Also if there are any tools to explain the occurrence of deadlock, it would help.
package main
import (
"log"
"sync"
)
const jobs = 10
const workers = 5
var wg sync.WaitGroup
func main() {
// create channel
dataStream := make(chan interface{})
signalStream := make(chan interface{})
// Generate workers
for i := 1; i <= workers; i++ {
wg.Add(1)
go worker(dataStream, signalStream, i*100)
}
// Generate jobs
for i := 1; i <= jobs; i++ {
dataStream <- i
}
close(dataStream)
// start consuming data
close(signalStream)
wg.Wait()
}
func worker(c <-chan interface{}, s <-chan interface{}, id int) {
defer wg.Done()
<-s
for i := range c {
log.Printf("routine - %d - %d \n", id, i)
}
}
答案1
得分: 1
将作业生成部分放入一个独立的goroutine中,即将整个jobs
循环放入goroutine中。如果不这样做,dataStream <- i
将会阻塞,你的程序将永远无法"开始消费数据"。
// 生成作业
go func() {
for i := 1; i <= jobs; i++ {
dataStream <- i
}
close(dataStream)
}()
链接:https://go.dev/play/p/ChlbsJlgwdE
英文:
Generate the jobs in a separate gorouine, i.e. put the whole jobs
loop into a goroutine. If you don't then dataStream <- i
will block and your program will never "start consuming data"
// Generate jobs
go func() {
for i := 1; i <= jobs; i++ {
dataStream <- i
}
close(dataStream)
}()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论