У меня есть код go, который в основном выполняет две подпрограммы go одновременно. Один из них отправляет 10 чисел типа int из (1-10) в буферизованный канал «ch» (емкость 4), а другой go программа считывает значения из канала с помощью for range loop
package main
import (
"fmt"
"sync"
"time"
"runtime"
)
func doSm(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 1; i <= 10; i++ {
fmt.Println("sending", i)
ch <- i
fmt.Println("sent", i)
}
close(ch)
}
func doSm2(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
time.Sleep(5 * time.Second)
for v := range ch {
fmt.Println("result:", v)
}
}
func main() {
runtime.GOMAXPROCS(1)
var wg sync.WaitGroup
ch := make(chan int, 4)
wg.Add(2)
go doSm(ch, &wg)
go doSm2(ch, &wg)
wg.Wait()
}
Проблема может быть обнаружена в выходных данных ниже.
doSm () отправляет 4 int через канал, а go планировщик блокирует процедуру go, пока doSm2 () не считывает эти 4 значения из канала. После этого буфер пуст и doSm () отправляет 1 int, а doSm2 () мгновенно его считывает. Теперь буфер снова пуст и готов к отправке 4 значений. Однако doSm () каким-то образом отправляет 5 значений (6, 7, 8, 9, 10), несмотря на свою емкость.
sending 1
sent 1
sending 2
sent 2
sending 3
sent 3
sending 4
sent 4
sending 5
result: 1
result: 2
result: 3
result: 4
result: 5
sent 5
sending 6
sent 6
sending 7
sent 7
sending 8
sent 8
sending 9
sent 9
sending 10
sent 10
result: 6
result: 7
result: 8
result: 9
result: 10
Есть идеи, почему это происходит? Или мне чего-то не хватает?