跳至主要內容
yomihon 書庫
整體狀況設定

鍵盤快捷鍵

⌘K / Ctrl K
搜尋
Esc
關閉搜尋或篩選
/
跳到導覽篩選(單鍵開啟時)
[
收合或展開側欄(單鍵開啟時)

關掉之後,/ 和 [ 都只會照瀏覽器原本的方式輸入;⌘K 與 Esc 不受影響。

設定
esc

↑↓ 選擇 ↵ 搜尋 esc 關閉

提早返回的管線

note檔案變更於
檔案變更於
類型
note
語言
zh-Hant
在 Obsidian 開啟留下自己的想法
檔案變更於
類型
note
語言
zh-Hant
在 Obsidian 開啟留下自己的想法
本頁內容 聲明的來源 1 對照閱讀 1 正文連到這篇 4

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 的出口。

作者標記的狀態 draft
設為 archived

設為 archived 之後,這裡不再有回到目前狀態的路。