【问题标题】:Deadlock while sending data to channel in slice of channels在通道片中向通道发送数据时发生死锁
【发布时间】:2021-05-21 11:51:08
【问题描述】:

将数据发送到通道切片中的整数通道会导致死锁

该代码预计会创建 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
    }

【问题讨论】:

  • 这些值应该在由 for 循环中的 goroutines 创建的通道中的 receive() 中接收
  • receive() 中,每个goroutine 都在一个单独的通道channel[0] to channel[4] 上,该通道应该将整数值发送到fanin。这些值将在频道fanInChan 上的main() 中接收。
  • 哎呀,我的错,我读错了代码。对不起。

标签: go slice channel


【解决方案1】:

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

  • 阻止从频道接收&lt;- channel
  • 阻止将channel &lt;- value 发送到频道
  • 关闭时出现恐慌close(channel)

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

在使用这些通道之前,您应该在 channels 数组中初始化通道。

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

go send(channels) 行之前插入它并运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 2011-08-24
    • 1970-01-01
    • 2015-05-20
    相关资源
    最近更新 更多