當被問到為什麼用go語言,一定不得不提的是go語言的併發程式編寫。在c語言中編寫非常繁瑣複雜的併發程式在go語言中總是顯得如此便捷。
go中併發程式依靠的是兩個:goroutine和channel
對於初學者,goroutine直接理解成為執行緒就可以了。當對乙個函式呼叫go,啟動乙個goroutine的時候,就相當於起來乙個執行緒,執行這個函式。
實際上,乙個goroutine並不相當於乙個執行緒,goroutine的出現正是為了替代原來的執行緒概念成為最小的排程單位。一旦執行goroutine時,先去當先執行緒查詢,如果執行緒阻塞了,則被分配到空閒的執行緒,如果沒有空閒的執行緒,那麼就會新建乙個執行緒。注意的是,當goroutine執行完畢後,執行緒不會**推出,而是成為了空閒的執行緒。
關於goroutine的理解,推薦看這個帖子:
使用非常簡單,在函式前增加乙個go
f(11)
go f(11) //這個是讓f()函式作為goroutine執行
但是go有乙個缺點,主線程要等待乙個goroutine結束再處理怎麼辦?拿《學習go語言》中的乙個例子說明。
這裡的第18行為什麼要sleep? 這裡是為了等上面兩個go ready處理完成。
好了,這裡就出來了乙個需求:乙個goroutine結束後必須要向主線程傳輸資料,告訴主線程這個goroutine已經結束了。
這裡就引進了channel的概念
上面的例子就可以改為:
從這個程式得到的幾點資訊:
基本格式是 c := make(chan int)
int是說明這個管道能傳輸什麼型別的資料
c 是不是很形象
因為2和3啟動了兩個goroutine,每個goroutine都往管道輸出乙個1,因此主線程要接收兩次才能說明兩個goroutine都結束了
channel分為兩種:一種是有buffer的,一種是沒有buffer的,預設是沒有buffer的
ci := make(chan int) //無buffer
cj := make(chan int, 0) //無buffer
cs := make(chan int, 100) //有buffer
有緩衝的channel,因此要注意「放」先於「取」
無緩衝的channel,因此要注意「取」先於「放」
裡面的乙個例子很好:
同樣要先輸出hello world,使用有緩衝的channel和無緩衝的channel分別是這樣的:
var a string
var c = make(chan int, 10)
func f()
func main()
這裡有個緩衝,因此放入資料的操作c
var a string
var c = make(chan int)
func f()
func main()
由於c是無緩衝的channel,因此必須保證取操作
go語言中的channel魔法
談點對goroutine的理解
goroutine效果測試
effective go
Go語言 併發篇
go語言 併發篇 2012 06 06 09 55 by 軒脈刃,當被問到為什麼用go語言,一定不得不提的是go語言的併發程式編寫。在c語言中編寫非常繁瑣複雜的併發程式在go語言中總是顯得如此便捷。go中併發程式依靠的是兩個 goroutine和channel 對於初學者,goroutine直接理解...
Go語言併發
協程 本質上是一種使用者態執行緒,不需要作業系統來進行搶占式排程,且在真正的實現重寄存於執行緒中,因此,系統開銷極小,可以有效提高執行緒的任務併發性,從而避免多執行緒的缺點。使用協程的優點是程式設計簡單,結構清晰 缺點是需要語言的支援。協程最大優勢 輕量級 可以輕鬆建立上百萬個而不會導致系統資源衰竭...
Go語言基礎 併發
並行 多件事在同一時刻發生。併發 多件事在同一時間間隔發生。摘自 和 concurrent and parallel programming 上文如果用程式設計師的語言來講,cpu處理器相當於上圖的咖啡機的角色,任務相當於佇列中的人。一定要仔細閱讀此文 這篇文章提到了網路伺服器併發連線數 吐吞量 寬...