Идите каналы - что здесь происходит - PullRequest
0 голосов
/ 26 апреля 2019

Я учусь идти по каналам из примера Go Tour в упражнении с веб-сканером.

Насколько я понимаю,

go func ()

запускает функцию в фоновом режиме, если ничто не блокирует, он должен просто завершитьfunc и return.

Но похоже, что go Crawl () ниже ничего не делает.Я правильно понимаю?

package main

import (
    "fmt"
)

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)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {
    // TODO: Fetch URLs in parallel.
    // TODO: Don't fetch the same URL twice.
    // This implementation doesn't do either:
    if depth <= 0 {
        return
    }
    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("found: %s %q\n", url, body)
    for _, u := range urls {
        fmt.Println("u is ", u)
        go Crawl(u, depth-1, fetcher)
    }
    return
}

func main() {
    Crawl("https://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)
}

1 Ответ

2 голосов
/ 26 апреля 2019

Программа Go завершается, когда возвращается метод main пакета main.После этого программа (включая все программы) немедленно завершает работу.См. Спецификацию Go языка :

Выполнение программы начинается с инициализации основного пакета и последующего вызова функции main.Когда этот вызов функции возвращается, программа завершается.Он не ждет завершения других (неосновных) программ.

В этом случае ваш метод Crawl порождает несколько процедур и сразу же возвращает их без синхронизации с этими программами, ожидая их завершения.После этого поток управления возвращается к main, который достигает конца функции и неявно возвращается, останавливая вашу программу.Обратите внимание, что это поведение перемежения не является детерминированным - в некоторых случаях вы могли бы получить выходные данные от некоторых подпрограмм, но очень маловероятно, что они будут запланированы для выполнения так быстро.

Вам необходимореализовать механизм для Crawl блокирования в ожидании результатов запускаемых ею программ.Для этого есть несколько механизмов, наиболее распространенным и рекомендуемым является использование WaitGroup .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...