C語言中文網 目錄
首頁 > Go語言教程 > Go語言并發 閱讀:2,879

Go語言并發打印(借助通道實現)

前面的例子創建的都是無緩沖通道。使用無緩沖通道往里面裝入數據時,裝入方將被阻塞,直到另外通道在另外一個 goroutine 中被取出。同樣,如果通道中沒有放入任何數據,接收方試圖從通道中獲取數據時,同樣也是阻塞。發送和接收的操作是同步完成的。

下面通過一個并發打印的例子,將 goroutine 和 channel 放在一起展示它們的用法。
package main

import (
    "fmt"
)

func printer(c chan int) {

    // 開始無限循環等待數據
    for {

        // 從channel中獲取一個數據
        data := <-c

        // 將0視為數據結束
        if data == 0 {
            break
        }

        // 打印數據
        fmt.Println(data)
    }

    // 通知main已經結束循環(我搞定了!)
    c <- 0

}

func main() {

    // 創建一個channel
    c := make(chan int)

    // 并發執行printer, 傳入channel
    go printer(c)

    for i := 1; i <= 10; i++ {

        // 將數據通過channel投送給printer
        c <- i
    }

    // 通知并發的printer結束循環(沒數據啦!)
    c <- 0

    // 等待printer結束(搞定喊我!)
    <-c

}
運行代碼,輸出如下:
1
2
3
4
5
6
7
8
9
10

代碼說明如下:
  • 第 10 行,創建一個無限循環,只有當第 16 行獲取到的數據為 0 時才會退出循環。
  • 第 13 行,從函數參數傳入的通道中獲取一個整型數值。
  • 第 21 行,打印整型數值。
  • 第 25 行,在退出循環時,通過通道通知 main() 函數已經完成工作。
  • 第 32 行,創建一個整型通道進行跨 goroutine 的通信。
  • 第 35 行,創建一個 goroutine,并發執行 printer() 函數。
  • 第 37 行,構建一個數值循環,將 1~10 的數通過通道傳送給 printer 構造出的 goroutine。
  • 第 44 行,給通道傳入一個 0,表示將前面的數據處理完成后,退出循環。
  • 第 47 行,在數據發送過去后,因為并發和調度的原因,任務會并發執行。這里需要等待 printer 的第 25 行返回數據后,才可以退出 main()。

本例的設計模式就是典型的生產者和消費者。生產者是第 37 行的循環,而消費者是 printer() 函數。整個例子使用了兩個 goroutine,一個是 main(),一個是通過第 35 行 printer() 函數創建的 goroutine。兩個 goroutine 通過第 32 行創建的通道進行通信。這個通道有下面兩重功能。
  • 數據傳送:第 40 行中發送數據和第 13 行接收數據。
  • 控制指令:類似于信號量的功能。同步 goroutine 的操作。功能簡單描述為:
    • 第 44 行:“沒數據啦!”
    • 第 25 行:“我搞定了!”
    • 第 47 行:“搞定喊我!”

精美而實用的網站,提供C語言C++STLLinuxShellJavaGo語言等教程,以及socketGCCviSwing設計模式JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo