iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0

有時候你可能想分割來自通道的多個值,以便將它們發送到兩個獨立區域。
想像一下:你可能想要在一個通道上接收一系列操作指令,將它們發送給執行者,同時記錄操作日志。
與Unix系統的tee命令功能類似,我們用tee-channel來實現同樣的功能。你可以傳遞給它一個用作讀取的通道,它會返回兩個單獨的通道:

tee := func(
      done <-chan interface{},
      in <-chan interface{},
  ) (_, _ <-chan interface{}) { <-chan interface{}) {
      out1 := make(chan interface{})
      out2 := make(chan interface{})
go func() {
          defer close(out1)
          defer close(out2)
          for val := range orDone(done, in) {
              var out1, out2 = out1, out2 //1
 } }
}()
select {
case <-done:
case out1 <- val:
    out1 = nil //3
case out2 <- val:
    out2 = nil //3
}
      return out1, out2
  }
  1. 我們希望使用使用本地的變數,所以建立了他們的副本。
  2. 我們將使用一條select語句,以便寫入out1和out2不會彼此阻塞。 為了確保兩者都順利寫入,我們將
    執行select語句的兩個叠代。
  3. 一旦我們寫入了通道,我們將其副本設置為零,這樣繼續寫入將阻塞,而另一個通道可以繼續執行。
    注意寫入out1和out2是緊密耦合的。 直到out1和out2都被寫入,叠代才能繼續。
    通常這不是問題,因為無論如何,處理來自每個通道的讀取流程的吞吐量應該是tee之外的關注點,但值得注意。

這是一個快速調用示例:

done := make(chan interface{})
  defer close(done)
  out1, out2 := tee(done, take(done, repeat(done, 1, 2), 4))
  for val1 := range out1 {
      fmt.Printf("out1: %v, out2: %v\n", val1, <-out2)
}

上一篇
18.Or-done-channel
下一篇
20.The bridge-channel
系列文
Concurrency in go 讀書心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言