致命错误所有戈鲁廷都处于睡眠状态 - 死锁

我正在使用缓冲通道,我得到了我需要的正确输出。


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,

    }

}

但是当我使用unBuffered通道时,我得到了错误,这是致命的错误:所有goroutines都睡着了 - 死锁!为什么会发生这种情况以及如何解决这个问题?


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)

    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,

    }

}

我们什么时候会使用缓冲通道,什么时候会使用无缓冲通道 如何识别两个通道类别的用例?


德玛西亚99
浏览 106回答 1
1回答

皈依舞

如果缓冲区已满,则通过通道发送和接收将阻塞。对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它会立即阻塞。将第一个数据发送到通道后,除非读取,否则没有其他例程的空间将数据发送到通道。因此,发件人被阻止。您需要取消阻止从通道读取的主要例程。以便发送方找到空间继续向通道发送数据。现在wg.Wait() 阻塞并且不允许主例程(for 循环)从通道读取。一旦它开始从通道读取,被阻止的发送者也可以恢复并可以发送更多数据。做wg。wait() 在并发 go 例程中:go func() {&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(expertChannel)}()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go