简体   繁体   English

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

[英]fatal error all goroutines are asleep - deadlock

I am using buffered channel and i get a proper output what i need.我正在使用缓冲通道,我得到了我需要的合适的 output。

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,
    }
}

But when i am using unBuffered channel then i am getting error and that is fatal error: all goroutines are asleep - deadlock!但是当我使用无缓冲通道时,我得到了错误,这是致命的错误:所有的 goroutine 都在睡觉 - 死锁! why this happen and how to resolve this?为什么会发生这种情况以及如何解决这个问题?

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,
    }
}

when we will use buffered channel and when will use unbuffered channel how to identify the use case of both channel category?什么时候使用缓冲通道,什么时候使用无缓冲通道如何识别这两个通道类别的用例?

Send and receive over a channel are blocking if buffer is full.如果缓冲区已满,则通过通道发送和接收会阻塞。 And for unbuffered channel since it has no buffer unless the data is read at the other end it will block immediately.对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它将立即阻塞。

Once you send first data to channel, unless you read there is no space for other routines to send data to channel.一旦您将第一个数据发送到通道,除非您阅读,否则其他例程将没有空间将数据发送到通道。 So the senders are blocked.所以发件人被阻止了。

You need to unblock the main routine that is reading from the channel.您需要解除阻塞从通道读取的主程序。 So that the senders will find space to continue sending data to channel.这样发送方就会找到空间继续向通道发送数据。

Right now wg.Wait() is blocking and not allowing the main routine (for loop) to read from channel.现在 wg.Wait() 正在阻塞并且不允许主例程(for循环)从通道读取。 Once it starts reading from channel the blocked senders can also resume and can send further data.一旦它开始从通道读取,被阻止的发送者也可以恢复并发送更多数据。

Do wg.Wait() in a concurrent go routine:在并发的 go 例程中执行 wg.Wait() :

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM