我正在尝试将一个简单的PHP同步位移植到Go,但我很难理解并发在通道方面的工作原理。 PHP脚本发出请求以获取媒体库部分列表,然后发出请求以获取每个部分中的项目。如果该部分是电视节目列表,则它会要求每个节目获得所有季节,然后另一个节目在每个季节内获得剧集。
我正试着在皮蓬身上写作 - 去我期望的工作,但我没有运气。我已经在网上尝试了各种频道指南,但通常最终会出现死锁警告。目前这个例子警告item:=< -ch用作值,看起来不像是在等待goroutines返回。有没有人有任何想法我能做什么?
package main
import (
"fmt"
"time"
)
// Get all items for all sections
func main() {
ch := make(chan string)
sections := getSections()
for _, section := range sections {
go getItemsInSection(section, ch)
}
items := make([]string, 0)
for item := <- ch {
items = append(items, item)
}
fmt.Println(items)
}
// Return a list of the various library sections
func getSections() []string {
return []string{"HD Movies", "Movies", "TV Shows"}
}
// Get items within the given section, note that some items may spawn sub-items
func getItemsInSection(name string, ch chan string) {
time.Sleep(1 * time.Second)
switch name {
case "HD Movies":
ch <- "Avatar"
ch <- "Avengers"
case "Movies":
ch <- "Aliens"
ch <- "Abyss"
case "TV Shows":
go getSubItemsForItem("24", ch)
go getSubItemsForItem("Breaking Bad", ch)
}
}
// Get sub-items for a given parent
func getSubItemsForItem(name string, ch chan string) {
time.Sleep(1 * time.Second)
ch <- name + ": S01E01"
ch <- name + ": S01E02"
}
答案 0 :(得分:2)
首先,该代码无法编译,因为for item := <- ch
应为for item := range ch
现在的问题是你要么必须关闭频道,要么在goroutine内永远运行你的循环。
go func() {
for {
item, ok := <-ch
if !ok {
break
}
fmt.Println(item)
items = append(items, item)
}
}()
time.Sleep(time.Second)
fmt.Println(items)