- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在参加 Go Tour,感觉除了并发之外我对这门语言已经有了很好的理解。
slide 10是一个要求读者并行化网络爬虫的练习(并使其不包括重复,但我还没有到达那里。)
这是我目前所拥有的:
func Crawl(url string, depth int, fetcher Fetcher, ch chan string) {
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
ch <- fmt.Sprintln(err)
return
}
ch <- fmt.Sprintf("found: %s %q\n", url, body)
for _, u := range urls {
go Crawl(u, depth-1, fetcher, ch)
}
}
func main() {
ch := make(chan string, 100)
go Crawl("http://golang.org/", 4, fetcher, ch)
for i := range ch {
fmt.Println(i)
}
}
我的问题是,我应该把 close(ch)
调用放在哪里。
如果我在 Crawl
方法的某处放置一个 defer close(ch)
,那么程序最终会从一个生成的 goroutine 写入一个封闭的 channel ,因为对 Crawl
的调用将在生成的 goroutine 之前返回。
如果我省略了对 close(ch)
的调用,正如我所演示的那样,程序会在覆盖 channel 的主函数中死锁,因为当所有 goroutines 返回时, channel 永远不会关闭。
最佳答案
查看 Effective Go 的并行化部分导致解决方案的想法。本质上,您必须在函数的每个返回路径上关闭 channel 。实际上这是 defer 语句的一个很好的用例:
func Crawl(url string, depth int, fetcher Fetcher, ret chan string) {
defer close(ret)
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
ret <- err.Error()
return
}
ret <- fmt.Sprintf("found: %s %q", url, body)
result := make([]chan string, len(urls))
for i, u := range urls {
result[i] = make(chan string)
go Crawl(u, depth-1, fetcher, result[i])
}
for i := range result {
for s := range result[i] {
ret <- s
}
}
return
}
func main() {
result := make(chan string)
go Crawl("http://golang.org/", 4, fetcher, result)
for s := range result {
fmt.Println(s)
}
}
与您的代码的本质区别在于,每个 Crawl 实例都有自己的返回 channel ,而调用者函数在其返回 channel 中收集结果。
关于go - 围棋练习之旅#10 : Crawler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13217547/
我是docker的新手,我正在尝试将Angular示例项目“Tour of heros”进行docker化,您可以在这里找到: https://angular.io/generated/zips/to
当我点击“结束游览”按钮时,我无法再次开始 Bootstrap 游览。我搜索了所有 documentation ,但我还没有找到解决方案。 最佳答案 也试试 tour.restart()。我刚刚问了同
我正在浏览Tour C++中的Aliases模板。我不明白下面的代码以及如何使用它? template class Vector { public: using value_type = T;
我已经实现了intro.js到我的网站。但我只想在第一次访问时开始旅行。可能是通过使用cookie..网站是用html而不是php制作的.. 最佳答案 JavaScript cookie 是一种解决方
我想使用Knockout.js与 Bootstrap Tour 。特别是,我想将一些数据绑定(bind)点击处理程序附加到游览步骤中的按钮。 我创建了一个像这样的简单游览: var tour = ne
我正在学习着名的 Angular 教程,英雄之旅,但我正在努力迈出一步。 关于 sixth course, HTTP ,我们正在使用一种工具来模拟对 API 的 API 调用。 我想我遵循了所有步骤,
我正在做 Go 之旅,这部分是“slice 就像对数组的引用”。我根本没有更改此代码,所以我很好奇为什么它会耗尽内存。 最佳答案 不应该崩溃,可能是旅游网站有一段时间出了问题......目前任何方式,
A Tour of Go #23 : package main import ( "fmt" "math" ) func pow(x, n, lim float64) float64
无法将其分解为更小的示例...所以我使用 std::multimap 来存储一些值...这是一个简单的多项式类。 问题是最后一个函数,它将两个多项式相乘。当它与它们相乘时,它会产生一个具有多项式的多项
环境:Angular 5+ 来源:https://angular.io/tutorial 在 heroes.component.ts 类中有一个带冒号的赋值,如下所示: export class He
代码 let interestingNumbers = [ "Prime": [2, 3, 5, 7, 11, 13], "Fibonacci": [1, 1, 2, 3, 5, 8]
在 Bootstrap 演练中,我们有下一个和上一个按钮。在此点击下一步按钮,我们进入下一步。 但我想添加条件,如果该输入字段为空,则演练不应移至下一步,它应仅停留在当前步骤。 引用代码如下: rec
我是一名优秀的程序员,十分优秀!