golang 最吸引人的地方可能就是併發了,無論**的編寫上,還是效能上面,golang 都有絕對的優勢
學習乙個語言的併發特性,我喜歡實現乙個生產者消費者模型,這個模型非常經典,適用於很多的併發場景,下面我通過這個模型,來簡單介紹一下 golang 的併發程式設計
協程go
golang 為併發而生,啟動乙個協程的語法非常簡單,使用go
關鍵字即可
go func () ()
同步訊號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
生產者
如果stop
標誌不為false
,不斷地往通道裡面放product
,完成之後訊號量完成
func producer(wg *sync.waitgroup, products chan<- product, name int, stop *bool)
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)
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++
time.sleep(time.duration(1) * time.second)
stop = true // 設定生產者終止訊號
wgp.wait() // 等待生產者退出
close(products) // 關閉通道
wgc.wait() // 等待消費者退出
golang 併發程式設計之生產者消費者
golang 最吸引人的地方可能就是併發了,無論 的編寫上,還是效能上面,golang 都有絕對的優勢 學習乙個語言的併發特性,我喜歡實現乙個生產者消費者模型,這個模型非常經典,適用於很多的併發場景,下面我通過這個模型,來簡單介紹一下 golang 的併發程式設計 協程go golang 為併發而生...
併發程式設計之生產者消費者模型
在程式執行中,例如 爬蟲.1 從網路上爬取資料,這個階段,由於網路原因,一般速度是比較慢的 2 在這些資料中篩選我想要的東西,cpu執行速度很快,這個過程就是比較快的 那麼這樣子執行下來就會造成,我十分鐘爬取到的資料,我花一分鐘就處理完了.這就造成了,cpu要長時間在等待資料的到來.在我們實際生活中...
Java高併發程式設計之經典面試題 生產者與消費者執行緒
面試題如下 寫乙個固定容量的同步容器,擁有put get和getcount方法,要求能夠支援5個生產者執行緒以及10個消費者執行緒的阻塞呼叫。寫乙個容器擁有put get和getcount,這事不難,難點在於,這是乙個同步容器,就是說當有多個執行緒同時進行put和get的時候,不能出錯。進一步分析 ...