package main
import (
"fmt"
"time"
)
func send(ch chan int, size int) {
for i := size; i < size+10; i++ {
ch <- i
fmt.Printf("put val %v in channel\n", i)
}
// close(ch)
}
func main() {
ch1 := make(chan int, 2)
ch2 := make(chan int, 1)
// defer close(ch1)
// defer close(ch2)
go send(ch1, 0)
go send(ch2, 20)
time.Sleep(time.Second)
for {
select {
case val := <-ch1:
fmt.Printf("read val %v from chl\n", val)
case val := <-ch2:
fmt.Printf("read val %v from ch2\n", val)
case <-time.After(2 * time.Second): //这里是从阻塞的channel中超时返回的小技巧
fmt.Println("Time out")
return
}
}
}
Я запускаю этот код и получаю read val 2 from chl
раньше put val 2 in channel
. Я не знаю, как это происходит. Кажется разумным читать после ввода нового значения в канале 1.
Пример вывода:
put val 20 in channel
put val 0 in channel
put val 1 in channel
put val 2 in channel
read val 0 from chl
read val 1 from chl
read val 20 from ch2
read val 21 from ch2
put val 3 in channel
put val 21 in channel
put val 22 in channel
read val 2 from chl
read val 3 from chl
read val 4 from chl
read val 22 from ch2
read val 23 from ch2
put val 4 in channel
put val 5 in channel
put val 6 in channel
put val 7 in channel
read val 5 from chl
read val 6 from chl
read val 7 from chl
read val 8 from chl
put val 8 in channel
put val 9 in channel
read val 9 from chl
put val 23 in channel
put val 24 in channel
put val 25 in channel
read val 24 from ch2
read val 25 from ch2
put val 26 in channel
put val 27 in channel
read val 26 from ch2
read val 27 from ch2
read val 28 from ch2
put val 28 in channel
put val 29 in channel
read val 29 from ch2
Time out
val := <-ch1
случай может быть выполнен доfmt.Printf("put val %v in channel\n", i)
, но сразу послеch <- i
, потому что они находятся в 2-х горутинах, одна из которых является основной, а другая создаетсяgo send()
. Пожалуйста, поправьте меня. 18.11.2020