Golang併發模型:輕鬆入門流水線模型

Golang作爲一個實用主義的編程語言,非常注重性能,在語言特性上天然支持併發,它有多種併發模型,通過流水線模型系列文章,你會更好的使用Golang併發特性,提高你的程序性能。

這篇文章主要介紹流水線模型的流水線概念,後面文章介紹流水線模型的FAN-IN和FAN-OUT,最後介紹下如何合理的關閉流水線的協程。

Golang的併發核心思路

Golang併發核心思路是關注數據流動。數據流動的過程交給channel,數據處理的每個環節都交給goroutine,把這些流程畫起來,有始有終形成一條線,那就能構成流水線模型。

但我們先從簡單的入手。

從一個簡單的流水線入手

流水線並不是什麼新奇的概念,它能極大的提高生產效率,在當代社會流水線非常普遍,我們用的幾乎任何產品(手機、電腦、汽車、水杯),都是從流水線上生產出來的。以汽車爲例,整個汽車流水線要經過幾百個組裝點,而在某個組裝點只組裝固定的零部件,然後傳遞給下一個組裝點,最終一臺完整的汽車從流水線上生產出來。

簡單流水線.png

Golang的併發模型靈感其實都來自我們生活,對軟件而言,高的生產效率就是高的性能。

在Golang中,流水線由多個階段組成,每個階段之間通過channel連接,每個節點可以由多個同時運行的goroutine組成。

從最簡單的流水線入手。下圖的流水線由3個階段組成,分別是A、B、C,A和B之間是通道aCh,B和C之間是通道bCh,A生成數據傳遞給B,B生成數據傳遞給C。

流水線中,第一個階段的協程是生產者,它們只生產數據。最後一個階段的協程是消費者,它們只消費數據。下圖中A是生成者,C是消費者,而B只是中間過程的處理者。

car_pipeline.jpeg

舉個例子,設計一個程序:計算一個整數切片中元素的平方值並把它打印出來。非併發的方式是使用for遍歷整個切片,然後計算平方,打印結果。

我們使用流水線模型實現這個簡單的功能,從流水線的角度,可以分爲3個階段:

  1. 遍歷切片,這是生產者。
  2. 計算平方值。
  3. 打印結果,這是消費者。

下面這段代碼:

  • producer()負責生產數據,它會把數據寫入通道,並把它寫數據的通道返回。
  • square()負責從某個通道讀數字,然後計算平方,將結果寫入通道,並把它的輸出通道返回。
  • main()負責啓動producer和square,並且還是消費者,讀取suqre的結果,並打印出來。
package main

import (
    "fmt"
)

func producer(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, n := range nums {
            out <- n
        }
    }()
    return out
}

func square(inCh <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for n := range inCh {
            out <- n * n
        }
    }()

    return out
}

func main() {
    in := producer(1, 2, 3, 4)
    ch := square(in)

    // consumer
    for ret := range ch {
        fmt.Printf("%3d", ret)
    }
    fmt.Println()
}

結果:

➜  awesome git:(master) ✗ go run hi.go
  1  4  9 16

你有沒有發現,這流水線其實是個串行的!最原始的流水線就是串行的,這種原始能讓我們掌握流水線的思路。

流水線的特點

  1. 每個階段把數據通過channel傳遞給下一個階段。
  2. 每個階段要創建1個goroutine和1個通道,這個goroutine向裏面寫數據,函數要返回這個通道。
  3. 有1個函數來組織流水線,我們例子中是main函數。

如果你沒了解過流水線,建議自己把以上的程序寫一遍,如果遇到問題解決了,那才真正掌握了流水線模型的思路。

下一篇,我將介紹流水線模型的FAN-IN、FAN-OUT,歡迎關注。

如果這篇文章對你有幫助,請點個贊/喜歡,讓我知道我的寫作是有價值的,感謝。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章