@Skelman

Почему такой код в golang не выполняется параллельно?

Есть код, по всем правилам вначале должны вывестись результаты http запроса, а потом результаты функции calc. Но выводится изначально результат функции calc, а потом результат http запроса. При всем этом код не выполняется параллельно, так как по моим подсчетам время выполнении всей программы - это время выполнения функции calc и http запроса по отдельности.
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"
)

func main() {
	t1 := time.Now()
	t := make(chan int)
	r := make(chan response)

	go calc(t)
	go request(r)

	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-t:
			fmt.Println(msg1)
		case msg2 := <-r:
			fmt.Println(msg2)
		}
	}
	fmt.Println("elapsedTime:", time.Now().Sub(t1))
}

type response struct {
	URL string `json:"url"`
}

func request(str chan response) {
	resp, err := http.Get("https://httpbin.org/get")

	if err != nil {
		log.Fatalln(err)
	}
	var result response

	json.NewDecoder(resp.Body).Decode(&result)
	str <- result
}

func calc(total chan int) {
	var sum int

	for i := 0; i < 4000000000; i++ {
		sum += i
	}
	total <- sum
}
  • Вопрос задан
  • 406 просмотров
Решения вопроса 1
for i := 0; i < 4000000000; i++ {
    sum += i
  }

Этот код слишком интенсивно нагружает процессор, из-за чего не происходит своевременное переключение между горутинами. Если вы добавите даже небольшую задержку в миллисекунду в этом цикле, все отработает как надо - пока будет спать одна горутина, будет выполняться другая.

Если версия Go <1.5 , скорее всего по умолчанию используется только 1 ядро процессора. Поэтому, 1 высоконагруженная горутина "мешает" работе всех прочих.

В Go >= 1.5 значение этой переменной по умолчанию равно числу ядер/потоков процессора. Можно так же попробовать самостоятельно поменять значение runtime.GOMAXPROCS.
https://habr.com/ru/post/195574/
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы