Golang中的多并发

huangapple go评论75阅读模式
英文:

Multiple concurrency in golang

问题

我正在尝试将一个简单的同步 PHP 代码转换为 Go,但是在理解并发与通道的工作原理方面遇到了困难。PHP 脚本首先发送请求以获取媒体库部分的列表,然后发送请求以获取每个部分中的项目。如果该部分是电视节目列表,则会发送请求以获取所有季节,并发送另一个请求以获取每个季节中的剧集。

我尝试使用 Go 编写了一个我认为可以工作的 pidgeon-go 版本,但是没有成功。我尝试了一些在线的通道指南,但通常会出现死锁警告。目前,这个示例会警告 "item := <-ch" 用作值,并且似乎没有等待 goroutine 返回的样子。有人有任何想法我该怎么做吗?

package main

import (
	"fmt"
	"time"
)

// 获取所有部分的所有项目
func main() {

	ch := make(chan string)
	sections := getSections()

	for _, section := range sections {
		go getItemsInSection(section, ch)
	}

	items := make([]string, 0)

	for item := range ch {
		items = append(items, item)
	}

	fmt.Println(items)

}

// 返回各个库部分的列表
func getSections() []string {

	return []string{"高清电影", "电影", "电视节目"}

}

// 获取给定部分中的项目,注意某些项目可能会生成子项目
func getItemsInSection(name string, ch chan string) {

	time.Sleep(1 * time.Second)

	switch name {

	case "高清电影":
		ch <- "阿凡达"
		ch <- "复仇者联盟"

	case "电影":
		ch <- "异形"
		ch <- "深渊"

	case "电视节目":
		go getSubItemsForItem("24", ch)
		go getSubItemsForItem("绝命毒师", ch)

	}

}

// 获取给定父项的子项目
func getSubItemsForItem(name string, ch chan string) {

	time.Sleep(1 * time.Second)

	ch <- name + ": S01E01"
	ch <- name + ": S01E02"

}

希望对你有帮助!

英文:

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 (
&quot;fmt&quot;
&quot;time&quot;
)
// 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 := &lt;- ch {
items = append(items, item)
}
fmt.Println(items)
}
// Return a list of the various library sections
func getSections() []string {
return []string{&quot;HD Movies&quot;, &quot;Movies&quot;, &quot;TV Shows&quot;}
}
// 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 &quot;HD Movies&quot;:
ch &lt;- &quot;Avatar&quot;
ch &lt;- &quot;Avengers&quot;
case &quot;Movies&quot;:
ch &lt;- &quot;Aliens&quot;
ch &lt;- &quot;Abyss&quot;
case &quot;TV Shows&quot;:
go getSubItemsForItem(&quot;24&quot;, ch)
go getSubItemsForItem(&quot;Breaking Bad&quot;, ch)
}
}
// Get sub-items for a given parent
func getSubItemsForItem(name string, ch chan string) {
time.Sleep(1 * time.Second)
ch &lt;- name + &quot;: S01E01&quot;
ch &lt;- name + &quot;: S01E02&quot;
}

答案1

得分: 2

首先,该代码无法编译,因为for item := &lt;- 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)

<kbd>playground</kbd>

英文:

First, that code doesn't compile because for item := &lt;- 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 := &lt;-ch
if !ok {
break
}
fmt.Println(item)
items = append(items, item)
}
}()
time.Sleep(time.Second)
fmt.Println(items)

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2014年8月17日 23:59:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/25350945.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定