golang中的多重并发

时间:2014-08-17 15:59:34

标签: concurrency go

我正在尝试将一个简单的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"

}

1 个答案:

答案 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)

playground