英文:
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)
}
输出:-
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
}
英文:
Sending data to integer channel in slice of channels is resulting into deadlock
The code is expected to create 5 (+1 fanInChan
) channels. These channels are used for send integer values through send()
and receive the same in receive()
and finally Fan-in the them to fanInChan
.
Code:-
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)
}
OutPut:-
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
Problem is starting in a for loop inside send()
for i := 0; i < 100; i++ {
channels[i%5] <- i
}
答案1
得分: 3
语句channels := make([]chan int, 5)
正在分配一个包含空通道的数组,该数组具有以下特性:
- 阻塞从通道接收
<- channel
的操作 - 阻塞将值发送到通道
channel <- value
的操作 - 在关闭通道
close(channel)
时引发恐慌
因此,在接收整数值之前,您必须单独初始化每个通道。
在使用这些通道之前,您应该在channels
数组中初始化这些通道。
for i := range channels {
channels[i] = make(chan int)
}
将此代码插入到go send(channels)
之前的行,并运行。
英文:
The statement channels := make([]chan int, 5)
is allocating a array with nil channels which
- Blocks receiving
<- channel
from channel - Blocks sending
channel <- value
into channel - panics on closing
close(channel)
So you have to initialize each channel individually to recive integer values.
You should init the channels in the channels
array before using those.
for i := range channels {
channels[i] = make(chan int)
}
Insert this just before the line go send(channels)
and run.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论