将数据发送到通道切片中的通道时出现死锁

Deadlock while sending data to channel in slice of channels

向通道切片中的整数通道发送数据导致死锁

该代码预计会创建 5 (+1 fanInChan) 个通道。这些通道用于通过 send() 发送整数值并在 receive() 中接收相同值,最后将它们扇入到 fanInChan.

代码:-

package main

import (
    "fmt"
    "sync"
)

func main() {
    defer fmt.Println("About to exit!")
    fmt.Println("Started")

    channels := make([]chan int, 5)
    fanInChan := make(chan int)

    go send(channels)
    go recive(fanInChan, channels)

    for val := range fanInChan {
        fmt.Println("Fanin", val)
    }
}
func send(channels []chan int) {
    defer fmt.Println("Send Ended")
    fmt.Println("Send Started")

    for i := 0; i < 100; i++ {
        channels[i%5] <- i
    }

    for i := 0; i < 5; i++ {
        close(channels[i])
    }
}

func recive(fanin chan<- int, channels []chan int) {
    defer fmt.Println("Recive Ended")
    fmt.Println("Recive Started")

    var wg sync.WaitGroup
    wg.Add(5)

    for i := 0; i < 5; i++ {
        go func(inew int) {
            defer wg.Done()
            fmt.Println(inew)
            for v := range channels[inew] {
                fanin <- v
            }
        }(i)
    }

    wg.Wait()
    close(fanin)
}

Golang PlayGround

输出:-

Started
Send Started
Recive Started
4
1
2
3
0
fatal error: all goroutines are asleep - deadlock!
... //You can see rest on playground link above

问题开始于 send()

中的 for 循环
for i := 0; i < 100; i++ {
        channels[i%5] <- i
    }

语句channels := make([]chan int, 5)正在分配一个没有通道的数组

  • 阻止从频道
  • 接收<- channel
  • 阻止将 channel <- value 发送到频道
  • 关闭时恐慌 close(channel)

因此您必须单独初始化每个通道以接收整数值。

您应该在 channels 数组中初始化通道,然后再使用它们。

    for i := range channels {
        channels[i] = make(chan int)
    }

将其插入 go send(channels) 和 运行.

行之前