go - 与 channel 一起进入候车室( worker )

标签 go channel worker

我正在尝试在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/

相关文章:

go - path.join上升两个目录

go - 删除最后一条路径并复制新的最后一条

java - 如何使用 Java NIO 服务 1000 个并发连接

javascript - nodejs - 集群中的最佳 worker 数

java - 我可以在关机时进行 Swing 操作吗?

php - Gearman PHP, sendComplete 没有效果

http - golang 中 http POST 的预检问题

go - 无法发出 UDP 请求

java - Java中非阻塞写入的顺序

go - 使用同一 channel 的不同通话