iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Cloud Native

【하나, 둘, ready, get set, go】系列 第 16

【하나, 둘, ready, get set, go】Day 16 - channels

  • 分享至 

  • xImage
  •  

前情提要

昨天簡單介紹要如何使用 Goroutines,今天就繼續延續下去吧

今天要介紹的是了 channels (通道)

channels 具有 發送/接收 阻塞的特性,所以可以用來等待 Goroutines 完成工作

下面我們就來實際操作一下

實際操作

語法

ch := make(chan <TYPE>, <Buffered Size>)

ch <-

<-ch

Example

ch := make(chan string) // 透過 make 建立一個字串型別的 channels (通道)

ch <- "ok" // 傳值到 channels 裡面 (發送)

<-ch // 從 channels 裡面讀值出來 (接收)

Unbuffered vs Buffered

channels 又分為 (1)unbuffered (2)buffered 這兩種
預設宣告時如果沒給 buffer size 的話,就會是 unbuffered channels

有宣告的話,宣告時會長成像這樣 ch := make(chan string, 2)

既然有給了 buffer,當傳入超過 buffer size 的值時,就會發生阻塞 (Block)
當阻塞 (Block) 一直無法解決的話,就會變成死鎖 (Deadlock)

像是下面這個例子

package main

import "fmt"

func main() {
    ch := make(chan string, 2)    
    
    ch <- "Hello"
    ch <- "World"
    ch <- "!"    
    
    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

輸出結果如下

https://ithelp.ithome.com.tw/upload/images/20230904/20140363Kd2bUm5eR0.png

快速分辨

如果覺得分辨現在是 發送接收 太難的話,有個簡單的方法

就是看 channels 變數現在是位於 <- (通道操作符) 的左邊還是右邊

如果 channels 變數現在是位於 <- 的左邊的話,那麼現在就是 發送 (Example:ch <- "ok")

如果 channels 變數現在是位於 <- 的右邊的話,那麼現在就是 接收 (Example:<-ch)

是不是瞬間覺得變簡單了呢~

用 channels 改寫昨天 A Tour of Go 範例

package main

import (
    "fmt"
    "time"
)

func say(s string, ch chan string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
    ch <- "done"
}

func main() {
    ch := make(chan string) 
    
    go say("world", ch)
    go say("hello", ch)    
    
    v := <-ch
    vv := <-ch
    fmt.Println(v, vv)
}

下面就來講解用 channels 改寫後的 Code

func say(s string)

首先是原本的 func say(s string),這邊我們多傳遞一個 chan string 型別的 channels 變數
改寫後就變成 func say(s string, ch chan string) -> Line 8

接著在執行完後,向 channels 傳遞 done 字串 ch <- "done" -> Line 13

func main()

首先,我們先宣告一個 字串型別的 channels 變數 ch -> Line 17

接著將兩個 say() function 前面都加上 go 修飾字,加入 Goroutines,
並將 channels 變數 ch 傳入 say() -> Line 19~20

接著從 channels 中讀取在 Line 13 發送的 done 字串,並輸出 -> Line 22~24

輸出結果

從下圖可以看到,hello 跟 world 都分別輸出五次後,才輸出 done

https://ithelp.ithome.com.tw/upload/images/20230904/20140363pVZetuEDyu.png

總結

今天簡單介紹了 Goroutines 中的 channels 用法

個人覺得用起來算是簡單,應該可以快速上手

明天要來介紹的是 Goroutines 中的 select 用法

明天見~


上一篇
【하나, 둘, ready, get set, go】Day 15 - goroutines
下一篇
【하나, 둘, ready, get set, go】Day 17 - sync (上)
系列文
【하나, 둘, ready, get set, go】30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言