golang 併發程式設計之生產者消費者
golang 最吸引人的地方可能就是併發了,無論程式碼的編寫上,還是效能上面,golang 都有絕對的優勢
學習一個語言的併發特性,我喜歡實現一個生產者消費者模型,這個模型非常經典,適用於很多的併發場景,下面我通過這個模型,來簡單介紹一下 golang 的併發程式設計
go 併發語法
協程 go
協程是 golang 併發的最小單元,類似於其他語言的執行緒,只不過執行緒的實現藉助了作業系統的實現,每次執行緒的排程都是一次系統呼叫,需要從使用者態切換到核心態,這是一項非常耗時的操作,因此一般的程式裡面執行緒太多會導致大量的效能耗費線上程切換上。而在 golang 內部實現了這種排程,協程在這種排程下面的切換非常的輕量級,成百上千的協程跑在一個 golang 程式裡面是很正常的事情
golang 為併發而生,啟動一個協程的語法非常簡單,使用 go
關鍵字即可
go func () {
// do something
}()
同步訊號 sync.WaitGroup
多個協程之間可以通過 sync.WaitGroup
同步,這個類似於 Linux 裡面的訊號量
var wg sync.WaitGroup // 申明一個訊號量
wg.Add(1) // 訊號量加一
wg.Done() // 訊號量減一
wg.Wait() // 訊號量為正時阻塞,直到訊號量為0時被喚醒
通道 chan
通道可以理解為一個訊息佇列,生產者往佇列裡面放,消費者從佇列裡面取。通道可以使用 close
關閉
ic := make(chan int, 10) // 申明一個通道
ic <- 10 // 往通道里面放
i := <- ic // 從通道里面取
close(ic) // 關閉通道
生產者消費者實現
定義產品類
這個產品類根據具體的業務需求定義
type Product struct {
name int
value int
}
生產者
如果 stop
標誌不為 false
,不斷地往通道里面放 product
,完成之後訊號量完成
func producer(wg *sync.WaitGroup, products chan<- Product, name int, stop *bool) {
for !*stop {
product := Product{name: name, value: rand.Int()}
products <- product
fmt.Printf("producer %v produce a product: %#v\n", name, product)
time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
}
wg.Done()
}
消費者
不斷地從通道里面取 product,然後作對應的處理,直到通道被關閉,並且 products 裡面為空, for 迴圈才會終止,而這正是我們期望的
func consumer(wg *sync.WaitGroup, products <-chan Product, name int) {
for product := range products {
fmt.Printf("consumer %v consume a product: %#v\n", name, product)
time.Sleep(time.Duration(200+rand.Intn(1000)) * time.Millisecond)
}
wg.Done()
}
主執行緒
var wgp sync.WaitGroup
var wgc sync.WaitGroup
stop := false
products := make(chan Product, 10)
// 建立 5 個生產者和 5 個消費者
for i := 0; i < 5; i++ {
go producer(&wgp, products, i, &stop)
go consumer(&wgc, products, i)
wgp.Add(1)
wgc.Add(1)
}
time.Sleep(time.Duration(1) * time.Second)
stop = true // 設定生產者終止訊號
wgp.Wait() // 等待生產者退出
close(products) // 關閉通道
wgc.Wait() // 等待消費者退出
> 轉載請註明出處 > 本文連結:<http://hatlonely.github.io/2018/03/11/golang-%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85/>
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 併發設計模式---生產者/消費者模式設計模式
- Java多執行緒之併發協作生產者消費者設計模式Java執行緒設計模式
- GoLang中生產者消費者模式解決併發問題Golang模式
- [Java併發程式設計實戰] 阻塞佇列 BlockingQueue(含程式碼,生產者-消費者模型)Java程式設計佇列BloC模型
- 生產者消費者模式模式
- 生產者消費者模型模型
- 架構設計:生產者/消費者模式[0]:概述架構模式
- 多執行緒之生產者消費者執行緒
- 多執行緒併發如何高效實現生產者/消費者?執行緒
- Java多執行緒-併發協作(生產者消費者模型)Java執行緒模型
- 生產消費者模式模式
- 生產者與消費者之Android audioAndroid
- 九、生產者與消費者模式模式
- python 生產者消費者模式Python模式
- ActiveMQ 生產者和消費者demoMQ
- java編寫生產者/消費者模式的程式。Java模式
- Java 多執行緒之併發協作生產者消費者設計模式 JDK1.5.0 + 升級優化版Java執行緒設計模式JDK優化
- Java實現生產者和消費者Java
- 新手練習-消費者生產者模型模型
- Java實現生產者-消費者模型Java模型
- 生產者和消費者(.net實現)
- Java中的設計模式(二):生產者-消費者模式與觀察者模式Java設計模式
- 架構設計:生產者/消費者模式[4]:雙緩衝區架構模式
- python中多程式消費者生產者問題Python
- Python並行程式設計(九):多程式物件交換之pipe(管道)實現生產者-消費者模型Python並行行程程式設計物件模型
- 【java併發程式設計】Lock & Condition 協調同步生產消費Java程式設計
- 架構設計:生產者/消費者模式[2]:佇列緩衝區架構模式佇列
- 架構設計:生產者/消費者模式[3]:環形緩衝區架構模式
- 生產者消費者問題-C++程式碼實現C++
- java實現生產者消費者問題Java
- 阻塞佇列和生產者-消費者模式佇列模式
- linux 生產者與消費者問題Linux
- 直觀理解生產者消費者問題
- Java 生產者消費者模式詳細分析Java模式
- 多執行緒-生產者消費者問題程式碼1執行緒
- 讀者寫者與生產者消費者應用場景
- Java多執行緒——生產者消費者示例Java執行緒
- Qt基於QSemaphore的生產者消費者模型QT模型