我正在进行巡回演唱,我觉得除了并发之外,我对语言有很好的理解.
在幻灯片72上有一个练习,要求读者并行化一个网络爬虫(并使其不覆盖重复,但我还没有到那里.)
这是我到目前为止:
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)
} …Run Code Online (Sandbox Code Playgroud) 我正在进行golang之旅并进行最后一次练习,以便将Web爬虫更改为并行爬行而不是重复爬行(http://tour.golang.org/#73).我所改变的只是爬行功能.
var used = make(map[string]bool)
func Crawl(url string, depth int, fetcher Fetcher) {
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("\nfound: %s %q\n\n", url, body)
for _,u := range urls {
if used[u] == false {
used[u] = true
Crawl(u, depth-1, fetcher)
}
}
return
}
Run Code Online (Sandbox Code Playgroud)
为了使它并发,我在函数Crawl的调用之前添加了go命令,但是不是递归地调用Crawl函数,程序只找到" http://golang.org/ "页面而没有其他页面.
当我将go命令添加到函数Crawl的调用时,为什么程序不能正常工作?
很多时候在 Go 中开发 http 服务器时,我遇到了这个困境。
假设我想尽快回复客户http statuscode 200(然后在后面执行工作),这就是我通常这样做的原因:
我让我的主要 http 处理程序接收请求,我写http 200响应,然后我通过 a 发送一条消息channel(如果我有N工作人员在听channel,我正在使用 a buffered channelof N):
func myHttpHandler(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(200)
log(req)
}
func log(req *http.Request) {
msg := createLog(req)
if msg != nil {
channel <- msg
}
}
Run Code Online (Sandbox Code Playgroud)
我让我的听众(在 init 上被解雇)永远在那个频道上听:
func init() {
for i := 0; i < workerCount; i++ {
go worker(i, maxEntrySize, maxBufferSize, maxBufferTime)
}
}
func worker(workerID …Run Code Online (Sandbox Code Playgroud)