提早返回的管線
producer 計算三個平方,消費者只取第一個。剩下的 send 會怎樣?
package main
import (
"fmt"
"time"
)
func squares() (<-chan int, <-chan struct{}) {
out := make(chan int)
done := make(chan struct{})
go func() {
defer close(done)
defer close(out)
for _, n := range []int{1, 2, 3} {
out <- n * n
}
}()
return out, done
}
func main() {
values, done := squares()
fmt.Println(<-values)
select {
case <-done:
fmt.Println("stopped")
case <-time.After(50 * time.Millisecond):
fmt.Println("still blocked")
}
}
儲存為 main.go,執行 go run main.go。Go 1.27.0 的輸出:
1
still blocked
卡在第二次 send
無緩衝的 out 需要接收方。第一個值交出後,沒有人接第二個值;producer 無法返回,兩個 defer 也尚未執行。
50 ms 只讓範例顯示結果,並沒有修復阻塞。這個短程式會隨 main 結束;若相同模式用在持續運行的服務中,工作就會一直留著。
加一格 buffer 就能取消工作。 它只能暫存一個值,第三次 send 仍會阻塞。
可以取消的管線 加入取消訊號,並等待 producer 收尾。兩份程式的差別在 send 的出口。