Как планируются горутины

У меня есть несколько основных вопросов о том, как работают горутины.

Рассматриваемый код:

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
}
  1. Здесь мы создаем 50 горутин. Неужели все 50 из них не начнут работать, если основная горутина не будет заблокирована спящим режимом? Я хочу понять в целом, нужно ли блокировать основную горутину, чтобы запускались дочерние процедуры go.

  2. В функции updatePopulation нет ничего, что блокировало бы горутину. Я читал о совместном планировании и о том, что только когда одна горутина блокируется, другая выполняется. Но когда я запускаю это, горутины работают не по порядку. Это потому, что они запланированы для разных потоков, и эти потоки выполняются одновременно на разных ядрах ЦП и не ждут завершения другой горутины? Мое значение GOMAXPROCS равно 8.

  3. Я читал, что среда выполнения Go заранее создает несколько потоков и использует их для планирования горутин. Это за выполнение программы?

Прежде чем вы скажете, я знаю, что решение навести порядок — это использовать блокировку, но я беру этот пример, чтобы понять основы, а не пытаюсь решить проблему с помощью этого кода.

Я не отвечаю на этот вопрос, потому что в Интернете есть минимум 100 статей об этом. ;)

Christoph 12.07.2024 20:11

1) Вы не знаете, когда они начнут бегать. Однако они не будут ждать, пока основная горутина заблокируется. 2) Среда выполнения Go использует упреждающее расписание начиная с версии 1.14. Больше нет совместного планирования. 3) Да.

Burak Serdar 12.07.2024 20:54

это слишком широко и пока не показывает никаких исследований, но, возможно, это поможет вам начать - 1: среда выполнения является вытесняющей, вам не нужно блокировать, но без синхронизации у вас нет гарантии, что горутины будут выполняться или давать видимые результаты . Вы не можете рассуждать о том, что происходит с гонками данных. 2: порядок выполнения отсутствует, потому что горутины запускаются одновременно, вот что значит одновременность. 3: не имеет значения, когда создаются потоки, они создаются по мере необходимости. Конечно, они предназначены для каждого выполнения, вы не можете каким-то образом сохранять потоки после выхода из программы.

JimB 12.07.2024 20:54
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
3
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Нет никакой гарантии относительно того, когда горутина начнет работать, но она не будет ждать, пока вы заблокируете основную горутину.
  2. Планировщик является упреждающим, что означает, что он может и будет переводить вашу горутину в спящий режим и выполнять другую, даже если вы не заблокируете ее. Другие горутины также могут работать параллельно, и в этом случае им вообще не придется ждать.
  3. Все потоки выполняются для каждого выполнения программы. Планировщик не запускает потоки заранее. Он запускает их по требованию, по мере необходимости.

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