新的去。我正在尝试读取 map[int][]string
,将字符串 slice 写入中间 channel ,然后在写入所有内容后,将所有字符串从中间 channel 读回另一个 channel ,最后将 channel 读入另一个 goroutine。
我无法弄清楚什么是从中间 channel 读取的良好非阻塞方式。
package main
import (
"fmt"
)
func f1(c chan []string, q chan int) {
// intermediate channel
ic := make(chan []string, 10)
hmap := map[int][]string{
0: []string{"a", "b", "c"},
1: []string{"d", "e",},
2: []string{"f", "g", "h"},
}
// for every elem in hmap put the values into intermediate channel
for _, v := range hmap {
f2(v, ic)
}
// everything is in intermediate channel by now
// read all the []string and concatenate them into a slice in a
// non-blocking fashion
var strs []string
for v := range ic {
strs = append(strs, v...)
}
// strs := <-ic
fmt.Println(strs)
select {
case c <- strs:
fmt.Println("Received strings.")
default:
fmt.Println("did not receive anything.")
}
q <- 1
}
func f2(v []string, ic chan []string) {
select {
case ic <- v:
fmt.Println("Sent to intermediate channel:", v)
default:
fmt.Println("nothing to send...")
}
}
func f3(c chan []string) {
fmt.Println(<-c)
}
func main() {
c := make(chan []string, 10)
q := make(chan int)
go f1(c, q)
go f3(c)
fmt.Println(<-q) // to wait for the quit to be set
}
go run main.go
运行。
这个程序进入死锁状态。如何避免死锁?
最佳答案
正如@zerkms 在评论中所说,您需要在完成写入后关闭 channel ,否则 for v := range ic {
将阻塞。
package main
import (
"fmt"
)
func f1(c chan []string, q chan int) {
ic := make(chan []string, 10)
hmap := map[int][]string{
0: []string{"a", "b", "c"},
1: []string{"d", "e"},
2: []string{"f", "g", "h"},
}
for _, v := range hmap {
f2(v, ic)
}
// done writing strings, close the channel
close(ic)
var strs []string
for v := range ic {
strs = append(strs, v...)
}
fmt.Println(strs)
select {
case c <- strs:
fmt.Println("Received strings.")
default:
fmt.Println("did not receive anything.")
}
q <- 1
}
func f2(v []string, ic chan []string) {
select {
case ic <- v:
fmt.Println("Sent to intermediate channel:", v)
default:
fmt.Println("nothing to send...")
}
}
func f3(c chan []string) {
fmt.Println(<-c)
}
func main() {
c := make(chan []string, 10)
q := make(chan int)
go f1(c, q)
go f3(c)
fmt.Println(<-q) // to wait for the quit to be set
}
关于go - 如何通过go例程连接多个 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50458313/