四段代碼入門Go協程以及channel!

寫一個簡單的程序,使得一個協程用來向channel中寫如數據,一個用來讀取數據。git

import (
    "fmt"
    "strconv"
    "testing"
)
/**
在這個示例中,咱們有
  - 一個message做爲channel
  - 一個協程用來發送消息
  - 主協程用來接收消息
*/
func Test_message(t *testing.T)  {
    /**
    聲明一個長度爲 1 的channel
    */
    messages := make(chan string)

    /**
    該協程負責向channel發送數據,共發送五次
    */
    go func() {
        for i := 0; i < 5; i++ {
            messages <- "Hello, 這是第 " + strconv.Itoa(i) + " 次傳遞消息"
        }
    }()

    /**
    讀取channel中的數據,這是個阻塞的操做
    */
    for i := 0; i < 5; i++ {
        fmt.Println(<- messages)
    }
}

代碼樣例

而後下面是三段代碼,你們看以前能夠小思考下運行結果,最好本身動手測試下。github

假如向channel中寫入數據時,設置1秒鐘的延遲,那麼讀取channel數據的協程會阻塞嗎?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在這個示例中,咱們的副協程在向channel中寫入數據的時候,有一秒的延遲

而後咱們發現控制檯斷斷續續的打印出了內容

說明咱們從channel中讀取消息是個阻塞的行爲
 */
func Test_message1(t *testing.T)  {
    /**
    聲明一個長度爲 1 的channel
     */
    messages := make(chan string)

    /**
    該協程每隔一秒向channel發送一個數據
     */
    go func() {
        for i := 0; i < 5; i++ {
            time.Sleep(time.Second * 1)
            messages <- "Hello, 這是第 " + strconv.Itoa(i) + " 次傳遞消息"
        }
    }()

    /**
    讀取channel中的數據,這是個阻塞的操做
     */
    for i := 0; i < 5; i++ {
        fmt.Println(<- messages)
    }
}

固然是阻塞的,寫協程阻塞了,讀協程只能乾等着啊,這個問題好像有點(๑•ᴗ•๑)緩存

若是給讀協程設置一秒延遲,那麼寫協程會阻塞嗎?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在這個示例中,咱們向channel中讀取數據時,設置了一秒的延遲

而後咱們發現控制檯斷斷續續的打印出了內容

說明咱們向channel中寫入消息也是是個阻塞的行爲
它受到channel容量的限制,若是channel容量滿了,寫操做就會阻塞協程
*/
func Test_message2(t *testing.T)  {
    /**
    聲明一個長度爲一的channel
    */
    messages := make(chan int)

    /**
    該協程每隔一秒向channel發送一個數據
    */
    go func() {
        for i := 0; i < 5; i++ {
            messages <- i
            fmt.Println("Hello, 這是第 " + strconv.Itoa(i) + " 次傳遞消息")
        }
    }()

    /**
    讀取channel中的數據,這是個阻塞的操做
    */
    for i := 0; i < 5; i++ {
        <- messages
        time.Sleep(time.Second * 1)
    }
}

答案是會的,由於channel的容量是有限的,沒有消費者的話,生產者是不能繼續生產的。測試

如何給channel設置一個5的容積,那麼下面程序的運行結果會是怎麼樣的?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在這個示例中,咱們建立了一個有緩存channel

你們能夠自行執行如下,能夠看到前面6次打印很是快,後面三次則是斷斷續續的

這就是有緩衝的channel,即便沒有消費者,咱們依舊能夠向channel中寫入數據,
直到容量達到上限
*/
func Test_message3(t *testing.T)  {
    /**
    聲明一個容量爲5的channel
    */
    messages := make(chan int, 5)

    /**
    該協程持續的嘗試向channel中發送一個數據
    */
    go func() {
        for i := 0; i < 10; i++ {
            messages <- i
            fmt.Println("Hello, 這是第 " + strconv.Itoa(i) + " 次傳遞消息")
        }
    }()

    /**
    每隔一秒讀取一次channel中的數據,這是形成channel內元素逐漸累積
    */
    for i := 0; i < 5; i++ {
        <- messages
        time.Sleep(time.Second * 1)
    }
}

答案是前面6次打印很是快,後面三次則是斷斷續續的code

怎麼樣,是否是對協程和channel有了基本的認識了協程

https://github.com/fish-bugs/...get

相關文章
相關標籤/搜索