У меня есть несколько основных вопросов о том, как работают горутины.
Рассматриваемый код:
package main
import (
"fmt"
"time"
)
type Country struct {
Name string
Continent string
Population int32
}
func updatePopulation(c *Country, newBorns int32) {
c.Population += newBorns
fmt.Printf("New population of %v is %v\n", c.Name, c.Population)
}
func main() {
totalStates := 50 // total number of sources, (US states)
us := Country{"USA", "North America", 32000000}
for i := 0; i <= totalStates; i++ {
go updatePopulation(&us, int32(i))
}
time.Sleep(time.Second * 5) // this is just so that we don't need channels
}
Здесь мы создаем 50 горутин. Неужели все 50 из них не начнут работать, если основная горутина не будет заблокирована спящим режимом? Я хочу понять в целом, нужно ли блокировать основную горутину, чтобы запускались дочерние процедуры go.
В функции updatePopulation нет ничего, что блокировало бы горутину. Я читал о совместном планировании и о том, что только когда одна горутина блокируется, другая выполняется. Но когда я запускаю это, горутины работают не по порядку. Это потому, что они запланированы для разных потоков, и эти потоки выполняются одновременно на разных ядрах ЦП и не ждут завершения другой горутины? Мое значение GOMAXPROCS равно 8.
Я читал, что среда выполнения Go заранее создает несколько потоков и использует их для планирования горутин. Это за выполнение программы?
Прежде чем вы скажете, я знаю, что решение навести порядок — это использовать блокировку, но я беру этот пример, чтобы понять основы, а не пытаюсь решить проблему с помощью этого кода.
1) Вы не знаете, когда они начнут бегать. Однако они не будут ждать, пока основная горутина заблокируется. 2) Среда выполнения Go использует упреждающее расписание начиная с версии 1.14. Больше нет совместного планирования. 3) Да.
это слишком широко и пока не показывает никаких исследований, но, возможно, это поможет вам начать - 1: среда выполнения является вытесняющей, вам не нужно блокировать, но без синхронизации у вас нет гарантии, что горутины будут выполняться или давать видимые результаты . Вы не можете рассуждать о том, что происходит с гонками данных. 2: порядок выполнения отсутствует, потому что горутины запускаются одновременно, вот что значит одновременность. 3: не имеет значения, когда создаются потоки, они создаются по мере необходимости. Конечно, они предназначены для каждого выполнения, вы не можете каким-то образом сохранять потоки после выхода из программы.
Я не отвечаю на этот вопрос, потому что в Интернете есть минимум 100 статей об этом. ;)