Я следил за Go Tour, и я немного застреваю, когда речь заходит о гортанах. Я понимаю, что они очень легкие, и что каждый раз, когда goroutine блоки, еще один будет начать, но я не могу получить мою голову вокруг, как на самом деле работает этот пример:Как работают goroutines?
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(1000 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
Я понимаю, что goroutine запускается для функции say с аргументом «мир», но насколько я понимаю, это должно печатать «мир» пять раз и «привет» один раз. Однако я не понимаю, почему выход, как это:
hello
world
hello
world
hello
world
hello
world
hello
Из моего ограниченного понимания потоков из других языков, на выходе должно быть что-то вроде этого:
hello
world
world
world
world
world
или как это:
world
world
world
hello
world
world
Почему вторая строка выполняется пять раз? Делает ли что-либо под оператором go
классифицировать как часть процедуры go?
Также на следующий слайд-шоу что-то я не могу получить мою голову раунд снова:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
goroutine начинается во второй половине среза, а затем еще один для первого часть среза, однако значениям x
и y
присвоены два разных значения. Как я вижу, функция sum
отправит ее сумму на канал c
, а затем следующий sum
отправит сумму на тот же канал c
, так как двум переменным могут присваиваться два разных значения? Должен ли канал c
иметь одно значение sum
?
Я ценю, что это довольно длинный вопрос, но я не смог найти ответ на эти вопросы.
Ох. Кажется, я понял. Главное - это обычная рутина, как вы сказали. Привет будет напечатан, потому что главный блокируется сна в рутине. Поскольку всякий раз, когда процедура блокируется, новый запускает основные повторы 5 раз, но в то же время функция повторяется и 5 раз. Привет сначала печатается, потому что код перескакивает по процедуре, ожидая его сна. – Bula
Также это еще один вопрос относительно моего второго примера. Скажем, есть миллионы вызовов функций суммы с приходом к нему. Если программа не попадает в строку, которая блокирует программу до того, как сумма закончит вычисление, это значение будет потеряно правильно? – Bula
@ Була извините за запоздалый ответ. Да, main() является goroutine сам по себе и будет работать на 'Sleep()'. – VonC