這個是前段時間看到go語言的貢獻者與布道師 d**e cheney對go併發的建議或者叫使用的陷阱(不是我自己的建議),結合自己最近幾年對gorotine的使用,再回頭看這幾條建議,真的會茅塞頓開,覺得特別重要。這篇文章對併發的建議的章節位址d**e cheney 是 go 程式語言的開源貢獻者和專案成員。d**id 是技術社群中備受尊敬的聲音,他就軟體設計、效能和 go 程式語言等各種主題發表演講。d**id 在go語言歷程中,分享過很多關於golang語言的正確使用的文章。這是他的部落格位址。
這個建議應該比較容易理解,啟動乙個gorotine應該是執行程式的,自己執行或者被人呼叫執行,不應該啟動gorotine之後這個gorotine啥事都沒乾。
作者舉了乙個例子
}為了阻塞main gorotine不要直接退出,等待go func的執行,最後寫了乙個for的死迴圈,這樣的話,main gorotine就是通常所說的啥事都沒乾,毫無結果地執行。我們當然可以使用waitgroup去等待go func的結束。作者給我們的建議,既然我們只有乙個任務需要做,main gorotine就可以完成,為什麼要啟動乙個gorotine去做這個任務,而讓main gorotine去等待,完全可以讓main去做這個任務
}許多 go 程式設計師過度使用 goroutine,尤其是在他們剛開始的時候。與生活中的所有事物一樣,適度是成功的關鍵。
這個表述起來比較容易,平常開發中可能會被忽略,乙個物件提供了啟動使用goroutine的方法,那麼就必須提供關閉goroutine的方法,而且一般得原則的是誰呼叫誰關閉。
舉乙個我們專案開發中的例子
timer_go.go
package main
import (
"fmt"
"sync"
"time"
)type timergo struct
func newtimergo() *timergo
func (this *timergo) run(wg *sync.waitgroup) }}
func (this *timergo) sync()
func (this *timergo) close()
main.go
package main
func main()
這個例子比較容易理解,我們需要每隔三秒執行乙個非同步的任務,這個工作我們啟動乙個goroutine去執行,所以我們在main函式執行go timergo.run,我們也提供close的方法,通過乙個channal去關閉它。
原則就是,誰呼叫誰關閉。提供執行方法,就必須提供關閉方法。
這個原則我覺得應該是最重要的原則,而且在開發中最容易遇到的問題。我們前期也寫過很多這樣的**,而且我看大家使用的專案基本也都是在需要啟動乙個goroutine去執行**的時候是這樣寫的
go aaa()
go bbb()
go ccc()
很少有人去關心啟動的這三個goroutine應該在什麼情況下去關閉,應該怎麼關閉,他們得執行狀態是怎麼樣的,在服務重新啟動時候,是等待執行完畢還是強制中斷。
這個原則應該會指引我們去做一些可靠的架構和規劃。這個遇到的太多了,有必要花時間去整理這裡。
永遠不要在不知道何時停止的情況下啟動 goroutine
Go語言(Golang)高併發處理思路
go語言作為新興的語言,最近發展勢頭很是迅猛,其最大的特點就是原生支援併發。它使用的是 協程 goroutine 模型 和傳統基於 os 執行緒和程序實現不同,go語言的併發是基於使用者態的併發,這種併發方式就變得非常輕量,能夠輕鬆執行幾萬併發邏輯。go 的併發屬於 csp 併發模型的一種實現,cs...
GO 開發系列 基礎 Go 併發程式設計
併發和並行說明 併發特點 並行特點 go 協程 說明 乙個 go 執行緒上可以起多個協程,協程可以理解為是輕量級的執行緒 go 協程特點 go 併發原理 mpg 模型 詳見部落格 示例 package main import fmt time 向 intchan放入 1 8000 個數 func p...
Golang的併發安全
channel是go中代替共享記憶體的通訊方式,channel從底層實現上是一種佇列,在使用的時候需要通道的傳送方和接收方需要知道資料型別和具體通道。如果有一端沒有準備好或訊息沒有被處理會阻塞當前端。actor模型 在actor模型中,主角是actor,類似一種worker,actor彼此之間直接傳...