天天看點

Go語言_并發篇了解什麼是goroutine?goroutine的使用channel的使用channel的進一步了解:

當被問到為什麼用Go語言,一定不得不提的是Go語言的并發程式編寫。在C語言中編寫非常繁瑣複雜的并發程式在Go語言中總是顯得如此便捷。

Go中并發程式依靠的是兩個:goroutine和channel

對于初學者,goroutine直接了解成為線程就可以了。當對一個函數調用go,啟動一個goroutine的時候,就相當于起來一個線程,執行這個函數。

實際上,一個goroutine并不相當于一個線程,goroutine的出現正是為了替代原來的線程概念成為最小的排程機關。一旦運作goroutine時,先去當先線程查找,如果線程阻塞了,則被配置設定到空閑的線程,如果沒有空閑的線程,那麼就會建立一個線程。注意的是,當goroutine執行完畢後,線程不會回收推出,而是成為了空閑的線程。

使用非常簡單,在函數前增加一個go

f(11)

go f(11) //這個是讓f()函數作為goroutine運作

但是go有一個缺點,主線程要等待一個goroutine結束再處理怎麼辦?拿《學習go語言》中的一個例子說明。

<a href="http://images.cnblogs.com/cnblogs_com/yjf512/201206/201206060955122621.png"></a>

這裡的第18行為什麼要sleep? 這裡是為了等上面兩個go ready處理完成。

好了,這裡就出來了一個需求:一個goroutine結束後必須要向主線程傳輸資料,告訴主線程這個goroutine已經結束了。

這裡就引進了channel的概念

channel的意思用白話可以這麼了解:主線程告訴大家你開goroutine可以,但是我在我的主線程開了一個管道,你做完了你要做的事情之後,往管道裡面塞個東西告訴我你已經完成了。

上面的例子就可以改為:

<a href="http://images.cnblogs.com/cnblogs_com/yjf512/201206/201206060955132164.png"></a>

從這個程式得到的幾點資訊:

基本格式是 c := make(chan int)

int是說明這個管道能傳輸什麼類型的資料

c &lt;- 1

是不是很形象

&lt;- c

因為2和3啟動了兩個goroutine,每個goroutine都往管道輸出一個1,是以主線程要接收兩次才能說明兩個goroutine都結束了

<a href="http://blog.dccmx.com/2011/05/magic-of-channel-in-go/">http://blog.dccmx.com/2011/05/magic-of-channel-in-go/</a>

<a href="http://blog.dccmx.com/2012/03/small-problem-about-goroutine/">http://blog.dccmx.com/2012/03/small-problem-about-goroutine/</a>

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分别是這樣的:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<code>var a string</code>

<code>var c = make(chan</code><code>int</code><code>,</code><code>10</code><code>)</code>

<code> </code> 

<code>func f() {</code>

<code>    </code><code>a =</code><code>"hello, world"</code>

<code>    </code><code>c &lt;-</code><code>0</code>

<code>}</code>

<code>func main() {</code>

<code>    </code><code>go f()</code>

<code>    </code><code>&lt;-c</code>

<code>    </code><code>print(a)</code>

這裡有個緩沖,是以放入資料的操作c&lt;- 0先于取資料操作 &lt;-c

<code>var c = make(chan</code><code>int</code><code>)</code>

由于c是無緩沖的channel,是以必須保證取操作&lt;-c 先于放操作c&lt;- 0

本文轉自軒脈刃部落格園部落格,原文連結:http://www.cnblogs.com/yjf512/archive/2012/06/06/2537712.html,如需轉載請自行聯系原作者

繼續閱讀