go學習筆記_Routine和Channel

來源:互聯網
上載者:User

標籤:並發   go   channel   goroutine   

go語言並發編程上

傍晚抽空學習了下go語言的並發編程,從goroutinechannel機制,從開始的稀裡糊塗到現在撥開雲霧見太陽的感覺,學習的過程總是令人亢奮的!當然目前的理解還是不夠透徹的。下篇將舉例來分析下。

goroutine

類似開闢進程、線程做法,go語言所採用的為 goroutine 。用法極其簡單,也就是使用go關鍵字,使用方法有兩種:

  • 定義一個函數functionName,要非同步呼叫時使用語句go functionName即可。

  • 使用匿名函數,用法為go func(參數列表){函數執行體}(),說明最後一個()作用就是讓該函數執行。

下面簡單代碼加深下:

    /////////第一種範例程式碼:///////////    func sayHello(name string){        fmt.Println("hello"+name)    }    //主程式入口    func main(){        go sayHello("PMST")    }    /////////第二種範例程式碼://////////    //主程式入口    func main(){        go func(){            fmt.Println("hello world")        }()     //別忘記這裡的()    }

現在來講下go關鍵字作用,一旦將go放在函數之前,意味分配一個子routine讓這個函數自個玩去(有點自身自滅的感覺),而主routine則繼續該幹嘛幹嘛。打個比方,手頭有一堆資料,需要經過超級複雜,超級耗時的計算才能得出答案。顯然我們的主routine不可能只幹這一件事,它還有其他事情需要處理。因此,我們開闢一個routine讓其自個算去。

那麼問題來了,這麼做確實解決了主routine不被鎖死的問題,又能夠完成了耗時計算,可是計算出答案之後,如何回傳給主routine使用呢?

這也就是下面channel的使用了

channel

goroutine 之間如何進行資料的通訊?如下兩種:

  1. 共用記憶體記憶體空間。

  2. Go語言推薦的通訊機制channel

接下來是我對channel的一些理解:

  • Goroutine使用channel 接收或者發送值,而這些值只能是特定的類型,由自己指定,比如兩個routine之間相互傳值為int類型,那麼channel類型就是chan int

  • 通過make來建立channel,例如無緩衝ci := make(chan int),指定緩衝cib := make(chan int,2)。很明顯可以看出,區別在於後面的表述,後者表示給這個通道分類了2個緩衝空間,至於區別,下文馬上給出。

  • channel 通過<- 來接收和發送資料。例如 channel <- value ,顯然就是把值 value 發送到通道 channel 中; value := <- ch ,注意箭頭,表示從通道 channel 讀取資料給 value ,或者可以說從通道channel接收資料賦值給value。順便提及其他的寫法<- channel,顯然也是從通道讀取資料,但是沒有賦值給任何一個變數,因此表示丟棄!

關於channel的阻塞問題,我想有必要著重梳理下。請看下面的總結

首先通道的接收和發送都是阻塞的,除非與之對應的一端已經準備好。通過舉例來說明是最好不過了。

  1. 建立一個通道,channel_c := make(chan int),注意是沒有分配緩衝的。

  2. 隨後往通道寫入資料,channel_c <- value,由於沒有分配緩衝,因此這裡會被堵塞掉,換句話說就是卡死在這裡,只能等待,等待程式某個地方從該通道讀取資料!(ps:就好比非常短的管子,就往裡塞了一個資料,就要漏出來,因此我一直手”扶著”資料,騰不出手幹下面的事了。只有當接收方來拿資料了才能騰出手來幹別的事。)

  3. 2015.04.22 -> 對上面比喻修改。ps:上面比喻的不是很恰當,我想是不是可以這麼認為,channel是連通兩個routine的通道,當寄件者向channel裡發送資料,卻遲遲等不到接收者,但秉著盡職盡責的思想,始終等待在那個位置,即channel_c := make(chan int)這條發送語句處,直到接收者接收了通道資料,才可以進行下一條語句。那麼假如有緩衝就不同了,就好比一個驛站,拿著資料到通道這發送“郵件”,儘管可能沒有接收者,但是我卻可以先暫時放到“驛站”(緩衝)這裡,然後繼續幹自己的活,等下次再向通道發送資料時發現緩衝滿了,就只能耐心等待,除非這時有人來取資料,騰出緩衝空間了,才可以寫入資料。

  4. 現在換成從通道讀取資料,v := <- channel_c,分兩種情況:當channel_c通道中有資料時,那肯定不會堵塞,很順利的讀過來;當channel_c通道沒有資料時,那麼自然又堵死了,除非程式其它地方往通道寫入資料了!

  5. 最後講講關於分配了緩衝的通道,例如:channel := make(chan int,2)。假如這時候往通道寫入資料channel <- 2,由於分配了緩衝,意味著是我可以直接寫入,不會堵塞了,但這僅當我的緩衝區未滿的情況下才不會堵塞。下面往通道寫入一個channel <- 3,這是沒有問題的。不過緩衝已經填滿了!假如這時候你再寫的話就會堵塞,只有程式某個地方從改通道讀取資料騰出地方了,你才可以寫入!

go學習筆記_Routine和Channel

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.