dongmin1166 2014-08-17 15:59
浏览 29
已采纳

Golang中的多个并发

I'm trying to port a simple synchronous bit of PHP to Go, but am having a hard time getting my head around how concurrency works with regards to channels. The PHP script makes a request to get a list of media library sections, then makes requests to get the items within each of these sections. If the section is a list of TV Shows, it then makes a request for each show to get all the seasons and then another to get the episodes within each season.

I've trying writing in pidgeon-go what I expected to work, but I'm not having any luck. I've tried various channel guides online, but normally end up with deadlock warnings. Currently this example warns about item := <-ch used as value and doesn't look like it's waiting on the goroutines to return. Does anyone have any ideas what I can do?

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条回答 默认 最新

  • douchui1488 2014-08-17 16:26
    关注

    First, that code doesn't compile because for item := <- ch should be for item := range ch

    Now the problem is you either have to close the channel or run your loop forever inside a goroutine.

    go func() {
        for {
            item, ok := <-ch
            if !ok {
                break
            }
            fmt.Println(item)
            items = append(items, item)
    
        }
    }()
    time.Sleep(time.Second)
    fmt.Println(items)
    

    <kbd>playground</kbd>

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 像这种代码要怎么跑起来?
  • ¥15 怎么改成循环输入删除(语言-c语言)
  • ¥15 安卓C读取/dev/fastpipe屏幕像素数据
  • ¥15 pyqt5tools安装失败
  • ¥15 mmdetection
  • ¥15 nginx代理报502的错误
  • ¥100 当AWR1843发送完设置的固定帧后,如何使其再发送第一次的帧
  • ¥15 图示五个参数的模型校正是用什么方法做出来的。如何建立其他模型
  • ¥100 描述一下元器件的基本功能,pcba板的基本原理
  • ¥15 STM32无法向设备写入固件