Это полностью зависит от планирования ОС.Результаты приведенного выше кода не всегда будут одинаковыми.
main() started
After 1, capacity 1
After 2, capacity 2
After 3, capacity 3
1
2
3
4
After 4, capacity 0
After 5, capacity 0
After 6, capacity 1
After 7, capacity 2
After 8, capacity 3
5
6
7
8
9
After 9, capacity 0
After 10
main() stopped
Этот результат может быть таким же, как вы видели на детской площадке.Но это непредсказуемо, потому что мы не можем определить, как ОС планирует расписание выполнения подпрограмм.
Если я запускаю этот код на своей локальной машине, он будет отличаться при каждом его выполнении.См. Ниже:
Первый запуск
main() started
After 1, capacity 1
After 2, capacity 1
After 3, capacity 2
1
2
3
4
After 4, capacity 3
After 5, capacity 0
5
After 6, capacity 0
After 7, capacity 1
After 8, capacity 2
After 9, capacity 3
6
7
8
9
10
After 10
main() stopped
Второй запуск
main() started
After 1, capacity 1
After 2, capacity 2
1
2
3
After 3, capacity 2
After 4, capacity 0
4
5
After 5, capacity 1
After 6, capacity 0
After 7, capacity 1
After 8, capacity 2
6
7
8
9
After 9, capacity 3
After 10
main() stopped
10
Так что ответы на ваши вопросы будут
Получение канала (для 4) только что было выполнено до fmt.Printf
в основной функции.Это может отличаться при каждом исполнении.Попробуйте это на своем локальном компьютере.
Похоже на 1. Он только что прочитал range
перед len(c)
.
Основная программавыход перед чтением 10 из канала.В этом случае вам следует подождать, пока все элементы в канале будут прочитаны с использованием некоторых методов, таких как время сна, группа ожидания пакета синхронизации или другой канал.
Вы можете увидеть, как этоПрограмма работает, вставляя time.Sleep(time.Second)
между строк, которые вы хотите проверить.
Например, если вы спите в течение 1 секунды перед fmt.Println("main() stopped")
, вы всегда можете увидеть эхо 10
, потому что основная программа будетждать секунду.(1 секунда достаточно большая для чтения элемента из канала)
package main
import "fmt"
import "time"
func echo(c chan int) {
for num := range c {
fmt.Println(num)
}
fmt.Println("Done iterating")
}
func main() {
fmt.Println("main() started")
c := make(chan int, 3)
go echo(c)
c <- 1
fmt.Printf("After 1, capacity %v\n",len(c))
c <- 2
fmt.Printf("After 2, capacity %v\n",len(c))
c <- 3
fmt.Printf("After 3, capacity %v\n",len(c))
c <- 4 // blocks here
fmt.Printf("After 4, capacity %v\n",len(c))
c <- 5
fmt.Printf("After 5, capacity %v\n",len(c))
c <- 6
fmt.Printf("After 6, capacity %v\n",len(c))
c <- 7
fmt.Printf("After 7, capacity %v\n",len(c))
c <- 8
fmt.Printf("After 8, capacity %v\n",len(c))
c <- 9
fmt.Printf("After 9, capacity %v\n",len(c))
c <- 10
fmt.Printf("After 10\n")
time.Sleep(time.Second)
fmt.Println("main() stopped")
}