Tôi đã thử các Go Tour exercise #71golang: goroute với lựa chọn không chỉ dừng lại trừ khi tôi thêm một fmt.Print()
Nếu nó được chạy như go run 71_hang.go ok
, nó hoạt động tốt.
Tuy nhiên, nếu bạn sử dụng go run 71_hang.go nogood
, nó sẽ chạy vĩnh viễn.
Sự khác biệt duy nhất là số fmt.Print("")
thêm trong số default
trong tuyên bố select
.
Tôi không chắc chắn, nhưng tôi nghi ngờ một số loại vòng lặp vô hạn và điều kiện chủng tộc? Và đây là giải pháp của tôi.
Lưu ý: Nó không bế tắc như Go không throw: all goroutines are asleep - deadlock!
package main
import (
"fmt"
"os"
)
type Fetcher interface {
// Fetch returns the body of URL and
// a slice of URLs found on that page.
Fetch(url string) (body string, urls []string, err error)
}
func crawl(todo Todo, fetcher Fetcher,
todoList chan Todo, done chan bool) {
body, urls, err := fetcher.Fetch(todo.url)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("found: %s %q\n", todo.url, body)
for _, u := range urls {
todoList <- Todo{u, todo.depth - 1}
}
}
done <- true
return
}
type Todo struct {
url string
depth int
}
// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {
visited := make(map[string]bool)
doneCrawling := make(chan bool, 100)
toDoList := make(chan Todo, 100)
toDoList <- Todo{url, depth}
crawling := 0
for {
select {
case todo := <-toDoList:
if todo.depth > 0 && !visited[todo.url] {
crawling++
visited[todo.url] = true
go crawl(todo, fetcher, toDoList, doneCrawling)
}
case <-doneCrawling:
crawling--
default:
if os.Args[1]=="ok" { // *
fmt.Print("")
}
if crawling == 0 {
goto END
}
}
}
END:
return
}
func main() {
Crawl("http://golang.org/", 4, fetcher)
}
// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult
type fakeResult struct {
body string
urls []string
}
func (f *fakeFetcher) Fetch(url string) (string, []string, error) {
if res, ok := (*f)[url]; ok {
return res.body, res.urls, nil
}
return "", nil, fmt.Errorf("not found: %s", url)
}
// fetcher is a populated fakeFetcher.
var fetcher = &fakeFetcher{
"http://golang.org/": &fakeResult{
"The Go Programming Language",
[]string{
"http://golang.org/pkg/",
"http://golang.org/cmd/",
},
},
"http://golang.org/pkg/": &fakeResult{
"Packages",
[]string{
"http://golang.org/",
"http://golang.org/cmd/",
"http://golang.org/pkg/fmt/",
"http://golang.org/pkg/os/",
},
},
"http://golang.org/pkg/fmt/": &fakeResult{
"Package fmt",
[]string{
"http://golang.org/",
"http://golang.org/pkg/",
},
},
"http://golang.org/pkg/os/": &fakeResult{
"Package os",
[]string{
"http://golang.org/",
"http://golang.org/pkg/",
},
},
}
chọn không mang lại * vì * của báo cáo kết quả mặc định .Mặc dù tôi không chắc đó có phải là điều bạn không hiểu hoàn toàn hay không, bởi vì bạn đã đóng đinh các giải thích "mặc định" và GOMAXPROCS. – mna
Đó là chính xác những gì tôi không biết, cảm ơn! –
"chọn không mang lại do tuyên bố mặc định". là những gì tôi không biết. Cảm ơn. – Sungam