致命错误所有 goroutines 都睡着了 - 死锁
fatal error all goroutines are asleep - deadlock
我正在使用缓冲通道,我得到了我需要的正确输出。
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 通道时出现错误,那就是
致命错误:所有 goroutine 都在休眠 - 死锁!
为什么会发生这种情况以及如何解决?
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,
}
}
我们什么时候使用缓冲通道,什么时候使用非缓冲通道如何识别这两种通道类别的用例?
如果缓冲区已满,通道上的发送和接收将被阻塞。对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它将立即阻塞。
一旦您将第一个数据发送到通道,除非您阅读,否则没有 space 其他例程将数据发送到通道。所以发件人被阻止了。
您需要解锁正在从通道读取的主程序。以便发送者找到space继续向通道发送数据。
现在 wg.Wait() 正在阻塞并且不允许主例程(for 循环)从通道读取。一旦它开始从通道读取,被阻止的发件人也可以恢复并可以发送更多数据。
在并发 go 例程中执行 wg.Wait():
go func() {
wg.Wait()
close(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,
}
}
但是当我使用 unBuffered 通道时出现错误,那就是 致命错误:所有 goroutine 都在休眠 - 死锁! 为什么会发生这种情况以及如何解决?
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,
}
}
我们什么时候使用缓冲通道,什么时候使用非缓冲通道如何识别这两种通道类别的用例?
如果缓冲区已满,通道上的发送和接收将被阻塞。对于无缓冲通道,因为它没有缓冲区,除非在另一端读取数据,否则它将立即阻塞。
一旦您将第一个数据发送到通道,除非您阅读,否则没有 space 其他例程将数据发送到通道。所以发件人被阻止了。
您需要解锁正在从通道读取的主程序。以便发送者找到space继续向通道发送数据。
现在 wg.Wait() 正在阻塞并且不允许主例程(for 循环)从通道读取。一旦它开始从通道读取,被阻止的发件人也可以恢复并可以发送更多数据。
在并发 go 例程中执行 wg.Wait():
go func() {
wg.Wait()
close(expertChannel)
}()