我试图在goroutine函数中写入一个频道作为最后一个动作。
不幸的是,这不起作用。而waitGroup永远不会完成。
import (
"sync"
"github.com/SlyMarbo/rss"
"fmt"
)
func main() {
urls := []string{"http://rss.cnn.com/rss/edition.rss", "http://rss.time.com/web/time/rss/top/index.xml"}
var c = make(chan string)
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go receiveRss(url, &wg, c)
}
wg.Wait()
fmt.Println("==============DONE=================")
}
func receiveRss(url string, wg *sync.WaitGroup, c chan string) {
defer wg.Done()
feed, err := rss.Fetch(url)
if err != nil {
fmt.Println("Failed to retrieve RSS feed", err)
}
items := feed.Items
for _, item := range items {
c <- item.Title
}
}
用c <- item.Title
替换fmt.Println(item.Title)
时,会调用延迟函数并打印DONE。
答案 0 :(得分:1)
问题是我只是写信道。永远不要读它。 如果不这样做,频道将毫无用处。
解决方法是:
在启动goroutines的循环之后从通道读取:
for title := range c {
fmt.Println(title)
}
如果频道从未关闭,则会导致无限循环。 所以我写完之后就关闭了频道:
close(c)
以下是整个代码:
func main() {
urls := []string{"http://rss.cnn.com/rss/edition.rss", "http://rss.time.com/web/time/rss/top/index.xml"}
var c = make(chan []string)
var wg sync.WaitGroup
for _, url := range urls {
wg.Add(1)
go receiveRss(url, &wg, c)
}
for title := range c {
fmt.Println(title)
}
wg.Wait()
fmt.Println("==============DONE=================")
}
func receiveRss(url string, wg *sync.WaitGroup, c chan []string) {
defer wg.Done()
feed, err := rss.Fetch(url)
if err != nil {
fmt.Println("Failed to retrieve RSS feed", err)
}
items := feed.Items
var titles []string
for _, item := range items {
titles = append(titles, item.Title)
}
c <- titles
close(c)
}