Как правильно ограничить количество горутин

Я получаю строки 'stdin' URL, например: $ echo -e ' https://golang.org/\nhttps://godoc.org\nhttps://golang.org' | иди беги 1.го. Задача - получить с каждой WEB-страницы номер слова "Go". Но я не могу запускать более 5 процедур и могу использовать только стандартную библиотеку. Вот мой код:

    package main

    import (
      "fmt"
      "net/http"
      "bufio"
      "os"
      "regexp"
      "io/ioutil"
      "time"
    )

func worker(id int, jobs<-chan string, results chan<-int) {
  t0 := time.Now()
  for url := range jobs {
    resp, err := http.Get(url)
    if err != nil {
      fmt.Println("problem while opening url", url)
      results<-0
      //continue
    }
    defer resp.Body.Close()
    html, err := ioutil.ReadAll(resp.Body)
    if err != nil {
      continue
    }
    regExp:= regexp.MustCompile("Go")
    matches := regExp.FindAllStringIndex(string(html), -1)
    t1 := time.Now()
    fmt.Println("Count for", url, ":", len(matches), "Elapsed time:", 
t1.Sub(t0),  "works id", id)
    results<-len(matches)
  }
}

func main(){
  scanner := bufio.NewScanner(os.Stdin)
  jobs := make(chan string, 100)
  results := make(chan int, 100)
  t0 := time.Now()
  for w:= 0; w<5; w++{
    go worker(w, jobs, results)
  }
  var tasks int = 0
  res := 0
  for scanner.Scan() {
      jobs <- scanner.Text()
      tasks ++
  }
  close(jobs)
  for a := 1; a <= tasks; a++ {
    res+=<-results
  }
  close(results)
  t2 := time.Now()
  fmt.Println("Total:",res, "Elapsed total time:", t2.Sub(t0) );
}

Я думал, что это работает, пока я не передал более 5 URL (один из них был неправильным) в stdin. Выход был:

 goroutine 9 [running]:
 panic ...

Очевидно, что дополнительные маршруты были начаты. Как это исправить? Может быть, есть более удобный способ ограничить количество горутин?

1 ответ

маршрут 9 [работает]:

Некоторые программы запускаются во время выполнения и при извлечении из Интернета.

Глядя на свой код, вы только запустили 5 процедур.

Если вы действительно хотите знать, сколько запущенных подпрограмм вы используете, используйте runtime.Numgoroutine

Другие вопросы по тегам