我正在尝试在Go中创建简单的工作程序池。
在将 WaitGroup 添加到以下程序后,我面临死锁。
其背后的核心原因是什么?
当我不使用 WaitGroup 时,程序似乎运行正常。
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0001b2ea8)
程序 -package main
import (
"fmt"
"strconv"
"sync"
)
func main() {
workerSize := 2
ProcessData(workerSize)
}
// ProcessData :
func ProcessData(worker int) {
// Create Jobs Pool for passong jobs to worker
JobChan := make(chan string)
//Produce the jobs
var jobsArr []string
for i := 1; i <= 10000; i++ {
jobsArr = append(jobsArr, "Test "+strconv.Itoa(i))
}
//Assign jobs to worker from jobs pool
var wg sync.WaitGroup
for w := 1; w <= worker; w++ {
wg.Add(1)
// Consumer
go func(jw int, wg1 *sync.WaitGroup) {
defer wg1.Done()
for job := range JobChan {
actualProcess(job, jw)
}
}(w, &wg)
}
// Create jobs pool
for _, job := range jobsArr {
JobChan <- job
}
wg.Wait()
//close(JobChan)
}
func actualProcess(job string, worker int) {
fmt.Println("WorkerID: #", worker, ", Job Value: ", job)
}
最佳答案
一旦所有工作都消耗完了,您的工作人员将在for job := range JobChan
中等待更多数据。直到关闭 channel ,循环才会结束。
另一方面,您的主要goroutine正在等待wg.Wait()
,但未达到(注释掉)关闭状态。
此时,所有goroutine都处于阻塞状态,等待数据或 WaitGroup 完成。
最简单的解决方案是在将所有作业发送到 channel 后直接调用close(JobChan)
:
// Create jobs pool
for _, job := range jobsArr {
JobChan <- job
}
close(JobChan)
wg.Wait()
关于go - 与 channel 一起进入候车室( worker ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63966344/