<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 14.3 協程同步:關閉通道-對阻塞的通道進行測試 通道可以被顯式的關閉;盡管它們和文件不同:不必每次都關閉。只有在當需要告訴接收者不會再提供新的值的時候,才需要關閉通道。只有發送者需要關閉通道,接收者永遠不會需要。 繼續看示例 [goroutine2.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_14/goroutine2.go)(示例 14.2):我們如何在通道的 `sendData()` 完成的時候發送一個信號,`getData()` 又如何檢測到通道是否關閉或阻塞? 第一個可以通過函數 `close(ch)` 來完成:這個將通道標記為無法通過發送操作 `<-` 接受更多的值;給已經關閉的通道發送或者再次關閉都會導致運行時的 panic。在創建一個通道后使用 defer 語句是個不錯的辦法(類似這種情況): ``` ch := make(chan float64) defer close(ch) ``` 第二個問題可以使用逗號,ok 操作符:用來檢測通道是否被關閉。 如何來檢測可以收到沒有被阻塞(或者通道沒有被關閉)? ``` v, ok := <-ch // ok is true if v received value ``` 通常和 if 語句一起使用: ``` if v, ok := <-ch; ok { process(v) } ``` 或者在 for 循環中接收的時候,當關閉或者阻塞的時候使用 break: ``` v, ok := <-ch if !ok { break } process(v) ``` 可以通過 `_ = ch <- v` 來實現非阻塞發送,因為空標識符獲取到了發送給 `ch` 的任何東西。在示例程序 14.2 中使用這些可以改進為版本 goroutine3.go,輸出相同。 實現非阻塞通道的讀取,需要使用 select(參見第 [14.4](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/14.4.md) 節)。 示例 14.9-[goroutine3.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_14/goroutine3.go): ``` package main import "fmt" func main() { ch := make(chan string) go sendData(ch) getData(ch) } func sendData(ch chan string) { ch <- "Washington" ch <- "Tripoli" ch <- "London" ch <- "Beijing" ch <- "Tokio" close(ch) } func getData(ch chan string) { for { input, open := <-ch if !open { break } fmt.Printf("%s ", input) } } ``` 改變了以下代碼: - 現在只有 `sendData()` 是協程,`getData()` 和 `main()` 在同一個線程中: ``` go sendData(ch) getData(ch) ``` - 在 `sendData()` 函數的最后,關閉了通道: ``` func sendData(ch chan string) { ch <- "Washington" ch <- "Tripoli" ch <- "London" ch <- "Beijing" ch <- "Tokio" close(ch) } ``` - 在 for 循環的 `getData()` 中,在每次接收通道的數據之前都使用 `if !open` 來檢測: ``` for { input, open := <-ch if !open { break } fmt.Printf("%s ", input) } ``` 使用 for-range 語句來讀取通道是更好的辦法,因為這會自動檢測通道是否關閉: ``` for input := range ch { process(input) } ``` 阻塞和生產者-消費者模式: 在第 14.2.10 節的通道迭代器中,兩個協程經常是一個阻塞另外一個。如果程序工作在多核心的機器上,大部分時間只用到了一個處理器。可以通過使用帶緩沖(緩沖空間大于 0)的通道來改善。比如,緩沖大小為 100,迭代器在阻塞之前,至少可以從容器獲得 100 個元素。如果消費者協程在獨立的內核運行,就有可能讓協程不會出現阻塞。 由于容器中元素的數量通常是已知的,需要讓通道有足夠的容量放置所有的元素。這樣,迭代器就不會阻塞(盡管消費者協程仍然可能阻塞)。然后,這樣有效的加倍了迭代容器所需要的內存使用量,所以通道的容量需要限制一下最大值。記錄運行時間和性能測試可以幫助你找到最小的緩存容量帶來最好的性能。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看