为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
德玛西亚99 2022-08-30 21:44:20
我正在使用缓冲通道,我得到了我需要的正确输出。package mainimport (    "fmt"    "sync")var wg sync.WaitGrouptype 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 mainimport (    "fmt"    "sync")var wg sync.WaitGrouptype 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,    }}我们什么时候会使用缓冲通道,什么时候会使用无缓冲通道 如何识别两个通道类别的用例?
查看完整描述

1 回答

?
皈依舞

TA贡献1851条经验 获得超3个赞

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


将第一个数据发送到通道后,除非读取,否则没有其他例程的空间将数据发送到通道。因此,发件人被阻止。


您需要取消阻止从通道读取的主要例程。以便发送方找到空间继续向通道发送数据。


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


做wg。wait() 在并发 go 例程中:


go func() {

    wg.Wait()

    close(expertChannel)

}()


查看完整回答
反对 回复 2022-08-30
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号