GO_11:GO語言基礎之並發concurrency

來源:互聯網
上載者:User

標籤:通過   原因   str   設定   通訊   時間   sof   sleep   非同步   

並發Concurrency

  很多人都是衝著 Go 大肆宣揚的高並發而忍不住躍躍欲試,但其實從源碼的解析來看,goroutine 只是由官方實現的超級“線程池”而已。不過話說回來,每個執行個體 4~5KB的棧記憶體佔用和由於實現機制而大幅減少的建立和銷毀開銷,是製造 Go 號稱的高並發的根本原因。另外,goroutine 的簡單易用,也在語言層面上給予了開發人員巨大的遍曆。

  高並發當中一定要注意:並發可不是並行。

  並發主要由切換時間片來實現“同時”運行,而並行則是直接利用多核實現多線程的運行,但 Go 可以設定使用核心數,以發揮多核電腦的處理能力。

  goroutine 奉行通過通訊來共用記憶體,而不是共用記憶體來通訊。Go 語言主要是通過 Channe 技術通訊來實現記憶體的共用的,因為 channel 是一個通道,Go 是通過通道來通訊進行記憶體資料的共用。

讓我們先來看一個最簡單的 goroutine 案例:

package mainimport (    "fmt"    "time")func main() {    //啟用一個goroutine    go GoRun()    //這裡加一個休眠是因為主線程已啟動就執行完畢消亡來,子線程還來不及執行    time.Sleep(2 * time.Second)}func GoRun() {    fmt.Println("Go Go Go!!!")}

運行結果:

Go Go Go!!!

Channel

1. Channel 是 goroutine 溝通的橋樑,大都是阻塞同步的

2. 它是通過 make 建立,close 關閉

3. Channel 是參考型別

4. 可以使用 for range 來迭代,不斷操作 channel

5. 可以設定單向 或 雙向通道

6. 可以設定緩衝大小,在未被填滿前不會發生阻塞,即它是非同步

那麼針對上溯代碼我們不使用休眠,而使用 Channel 來實現我們想要的效果:

package mainimport (    "fmt")func main() {    //聲明建立一個通道,儲存類型為bool型    c := make(chan bool)    //啟用一個goroutine,使用的是匿名方法方式    go func() {        fmt.Println("Go Go Go!!!")        c <- true  //向 channel 中存入一個值    }()    //當程式執行完畢之後再從通道中取出剛才賦的值    <- c    /**    主線程啟動了一個匿名子線程後就執行到了:<-c , 到達這裡主線程就被阻塞了。只有當子線程向通道放入值後主線程阻塞才會被釋放    其實這個就是完成了訊息的發送     */}

上溯代碼可以修改為使用 for range 來進行訊息的發送:

package mainimport (    "fmt")func main() {    //聲明建立一個通道,儲存類型為bool型,這裡設定的channel就是雙向通道,既可以存也可以取    c := make(chan bool)    //啟用一個goroutine,使用的是匿名方法方式    go func() {        fmt.Println("Go Go Go!!!")        c <- true  //向 channel 中存入一個值        close(c)  //切記如果使用for range來進行取值的時候需要在某個地方進行關閉,否則會發生死結    }()    //從通道中迴圈取出剛才賦的值    for v := range c {        fmt.Println(v)    }}

  從以上代碼可以看出,一般使用的 Channel 都是雙向通道的,即:既可以取又可以存。那單向通道一般用於什麼情境下呢?

  單向通道又分為兩種,一種是只能讀取,一種是只能存放,一般用於參數類型傳遞使用。例如有個方法返回一個Channel類型,一般要求操作只能從這裡取,那麼此時它的用途就是只能存放類型,如果此時你不小心存資料,此時會發生panic 導致程式奔潰發生異常。那麼讀取類型的Channel同理。這樣做其實也是為了程式的安全性與健壯性,防止一些誤操作。

  這裡還有一個知識點,就是有緩衝的channel 和 無緩衝的channel的區別?

  make(chan bool, 1) 表示帶有一個緩衝大小的緩衝channel;make(chan bool) 表示一個無緩衝的channel

  無緩衝channel是阻塞的即同步的,而有緩衝channel是非同步。

  怎麼說?比如

  c1:=make(chan int)         無緩衝

  c2:=make(chan int,1)      有緩衝

  c1<-1                            

  無緩衝的 不僅僅是 向 c1 通道放 1 而是 一直要有別的攜程 <-c1 接手了 這個參數,那麼 c1<-1 才會繼續下去,要不然就一直阻塞著

  而 c2<-1 則不會阻塞,因為緩衝大小是1 只有當 放第二個值的時候 第一個還沒被人拿走,這時候才會阻塞。

  打個比喻

  無緩衝的  就是一個送信人去你家門口送信 ,你不在家 他不走,你一定要接下信,他才會走。

  無緩衝保證信能到你手上

  有緩衝的 就是一個送信人去你家仍到你家的信箱 轉身就走 ,除非你的信箱滿了 他必須等信箱空下來。

  有緩衝的 保證 信能進你家的郵箱

 

GO_11:GO語言基礎之並發concurrency

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.