致命错误所有goroutine都处于休眠状态-死锁

致命错误所有goroutine都处于休眠状态-死锁,go,concurrency,Go,Concurrency,我使用缓冲通道,我得到了一个适当的输出,我需要什么 package main import ( "fmt" "sync" ) var wg sync.WaitGroup type Expert struct { name string age int } func main() { fmt.Println("==== GoRoutines ====") expertChannel

我使用缓冲通道,我得到了一个适当的输出,我需要什么

package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup

type Expert struct {
    name string
    age  int
}

func main() {
    fmt.Println("==== GoRoutines ====")
    expertChannel := make(chan Expert, 3)
    wg.Add(1)
    go printHello()
    wg.Add(1)
    go addDataToChannel(expertChannel, "Name", 24)
    wg.Add(1)
    go addDataToChannel(expertChannel, "Name", 24)
    wg.Add(1)
    go addDataToChannel(expertChannel, "Name", 24)
    wg.Wait()
    close(expertChannel)
    for x := range expertChannel {
        fmt.Println("Expert Data :: ", x)
    }

}

func printHello() {
    for i := 1; i <= 5; i++ {
        fmt.Println("This is from PrintHello() Function where i = ", i)
    }
    defer wg.Done()

}

func addDataToChannel(c chan Expert, name string, age int) {
    defer wg.Done()

    c <- Expert{
        name,
        age,
    }
}
主程序包
进口(
“fmt”
“同步”
)
var wg sync.WaitGroup
类型专家结构{
名称字符串
年龄智力
}
func main(){
fmt.Println(“==GoRoutines==”)
expertChannel:=make(chan专家,3)
工作组.添加(1)
去打印Hello()
工作组.添加(1)
转到addDataToChannel(expertChannel,“名称”,24)
工作组.添加(1)
转到addDataToChannel(expertChannel,“名称”,24)
工作组.添加(1)
转到addDataToChannel(expertChannel,“名称”,24)
wg.Wait()
关闭(expertChannel)
对于x:=范围expertChannel{
fmt.Println(“专家数据:”,x)
}
}
func printHello(){

对于i:=1;i如果缓冲区已满,则通过通道发送和接收将被阻塞。对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它将立即阻塞

一旦您将第一个数据发送到通道,除非您读取,否则就没有空间让其他例程将数据发送到通道。因此,发送方被阻止

您需要取消阻止正在从通道读取数据的主例程。这样,发送方将找到空间继续向通道发送数据

现在wg.Wait()正在阻塞,不允许主例程(for循环)从通道中读取数据。一旦它开始从通道中读取数据,被阻塞的发送方也可以恢复并发送进一步的数据

在并发go例程中执行wg.Wait():

go func() {
    wg.Wait()
    close(expertChannel)
}()

我不明白为什么wg.Wait()会阻塞主例程?如果我使用您提到的代码,那么它会很好,那么为什么在没有声明新的go例程的情况下不工作呢?wg.Wait()在主例程中被调用。Wait()会阻塞,直到WaitGroup计数器为0。当所有预期的例程都调用wg.Done()时,它将为0。其他例程无法调用wg.Done(),因为它们在通道上发送数据时被阻止。通过允许运行x:=range expertChannel的
,您将确保从通道中提取值,以便发送方不会被阻止向其发送数据。
go func() {
    wg.Wait()
    close(expertChannel)
}()