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

成功: 進程退出代碼 0.

代碼說明:

  • 本例設計模式就是典型的生產者和消費者。生產者是第
  •  37 行的循環,而消費者是 printer() 函數。整個例子使用了兩個 goroutine,一個是 main(),一個是通過第 35 行 printer() 函數創建的 goroutine。兩個 goroutine 通過第 32 行創建的通道進行通信。這個通道有下面兩重功能。
  • 數據傳送:第 40 行中發送數據和第 13 行接收數據。
  • 控制指令:類似於信號量的功能。同步 goroutine 的操作。功能簡單描述爲:
  • 第 44 行:“沒數據啦!”
  • 第 25 行:“我搞定了!”
  • 第 47 行:“搞定喊我!”
  • 第 10 行,創建一個無限循環,只有當第 16 行獲取到的數據爲 0 時纔會退出循環。
  • 第 13 行,從函數參數傳入的通道中獲取一個整型數值。
  • 第 21 行,打印整型數值。
  • 第 25 行,在退出循環時,通過通道通知 main() 函數已經完成工作。
  • 第 32 行,創建一個整型通道進行跨 goroutine 的通信。
  • 第 35 行,創建一個 goroutine,併發執行 printer() 函數。
  • 第 37 行,構建一個數值循環,將 1~10 的數通過通道傳送給 printer 構造出的 goroutine。
  • 第 44 行,給通道傳入一個 0,表示將前面的數據處理完成後,退出循環。
  • 第 47 行,在數據發送過去後,因爲併發和調度的原因,任務會併發執行。這裏需要等待 printer 的第 25 行返回數據後,纔可以退出 main()。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章