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

Go做爲一個實用主義的編程語言,很是注重性能,在語言特性上自然支持併發,Go併發模型有多種模式,經過流水線模型系列文章,你會更好的使用Go的併發特性,提升的程序性能。git

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

Golang的併發核心思路

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

但咱們先從簡單的入手。編程

從一個簡單的流水線入手

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

car_pipeline.jpeg

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

在Golang中,流水線由多個階段組成,每一個階段之間經過channel鏈接,每一個節點能夠由多個同時運行的goroutine組成。less

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

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

簡單流水線.png

舉個例子,設計一個程序:計算一個整數切片中元素的平方值並把它打印出來。非併發的方式是使用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,歡迎關注。

完整示例代碼

本文全部代碼都在倉庫,可查看完整示例代碼:https://github.com/Shitaibin/...

併發系列文章推薦

  1. 若是這篇文章對你有幫助,請點個贊/喜歡,鼓勵我持續分享,感謝。
  2. 個人文章列表,點此可查看
  3. 若是喜歡本文,隨意轉載,但請保留此原文連接

一塊兒學Golang-分享有料的Go語言技術

相關文章
相關標籤/搜索