GoLang - 多 goroutine 透過 Channels 協同處理範例

在這幾篇,會以 Go 語言的入門基礎進行逐步說明,本篇針對 多 goroutine 透過 channel 協同處理 進行說明

UnBuffered 情況下,透過設計一個負責 witheData 的 goroutine 與 readData goroutine,當 write 將值寫入 channel,在透過 read 將 channel 的值取出。另外,透過 sync WaitGroup 等待 thread 執行,確保內容有正確被輸出:

package main

import (
  "fmt"
  "sync"
)

var wg sync.WaitGroup

//writeData
func writeData(intChan chan int) {
  for i := 1; i <= 50; i++ {
    intChan <- i
    fmt.Printf("writeData = %v\n", i)
  }
  close(intChan)
}

//readData
func readData(intChan chan int) {

  for {
    v, ok := <-intChan
    if !ok {
      break
    }
    fmt.Printf("readData = %v\n", v)
  }
  wg.Done()
}

func main() {
  wg.Add(1)
  intChan := make(chan int)
  go writeData(intChan)
  go readData(intChan)
  wg.Wait()

}

查看輸出結果,會依序逐步寫入及讀取

readData = 1
writeData 1
writeData 2
readData = 2
readData = 3
writeData 3
writeData 4
readData = 4
readData = 5
writeData 5
writeData 6
readData = 6
readData = 7
writeData 7
writeData 8
readData = 8
readData = 9
writeData 9
writeData 10
readData = 10
...
writeData 50
readData = 50

Buffered channel 的情況下,兩個 goroutine 在讀寫操作同一個 channel 時

package main

import (
  "fmt"
  "sync"
)

var wg sync.WaitGroup

//writeData
func writeData(intChan chan int) {
  for i := 1; i <= 50; i++ {
    intChan <- i
    fmt.Printf("writeData = %v\n", i)
  }
  close(intChan)
}

//readData
func readData(intChan chan int) {

  for {
    v, ok := <-intChan
    if !ok {
      break
    }
    fmt.Printf("readData = %v\n", v)
  }
  wg.Done()
}

func main() {
  wg.Add(1)
  intChan := make(chan int, 50)
  go writeData(intChan)
  go readData(intChan)
  wg.Wait()

}

輸出結果

readData = 1
writeData 1
writeData 2
writeData 3
writeData 4
writeData 5
writeData 6
writeData 7
writeData 8
writeData 9
writeData 10
writeData 11
writeData 12
writeData 13
writeData 14
writeData 15
writeData 16
writeData 17
writeData 18
writeData 19
writeData 20
writeData 21
writeData 22
writeData 23
writeData 24
writeData 25
writeData 26
writeData 27
readData = 2
readData = 3
readData = 4
readData = 5
readData = 6
readData = 7
readData = 8
readData = 9
readData = 10
readData = 11
readData = 12
readData = 13
readData = 14
...
writeData 48
writeData 49
writeData 50
...
readData = 49
readData = 50