Golang 筆記
  • Introduction
  • 安裝Golang
    • 本地編譯與安裝第三方套件
    • 第一個 GO 程式
    • export 與 import
    • 使用 go mod
  • 基本工具
  • DataBase操作
    • MySQL
    • 使用 ORM
    • MongoDB
  • 基本語法
    • Variable
    • BSON
    • JSON
    • 時間相關
    • Interface
    • Error
    • 型別
    • 字串
    • defer
    • panic, recover
    • Channel 與Goroutine
      • 讀寫鎖
      • for select 與 for range
      • UnBuffered channel 與 Buffered channel
    • Function
    • pointer
    • regExp
    • fmt
    • Make vs New
    • struct
    • Array, Slice 陣列
    • map
  • 核心模組
    • Reflect
    • File
    • Signal
    • BuiltIn
    • Sync
    • IO
    • Sort
    • http
    • crypto
    • context
  • 第三方模組
    • Dom Parser
    • gin 框架
    • Websocket
    • Iris框架
      • 讀取 Body 資料
      • 相關範例
    • Fiber 框架
    • 自動重啟 server 工具
    • go-jwt
  • 測試
  • 原始碼解析
  • 常見問題
    • 資料存取不正確
    • Data races
Powered by GitBook
On this page
  • 簡介:
  • Context vs Channel

Was this helpful?

  1. 核心模組

context

https://pkg.go.dev/context

PreviouscryptoNext第三方模組

Last updated 3 years ago

Was this helpful?

簡介:

當我們使用 goroutine 時需要一個地方來儲存互相會共用的變數或是讓 goroutine 在特定情況下停止執行,此時可以使用 context。

包含以下方法

WithCancel
WithDeadline
WithTimeout
WithValue

使用前需要把 Background 傳進去

context.Background()

之後放到 WithDeadline 或 WithTimeout 或 WithCancel,最後如果要傳值再放進 WithValue。

在 goroutine 裡面使用 select,當 context timeout 或 cancel 後會觸發 select 裡面的

case <-ctx.Done():

範例:

func someHandler() {
    ctx, cancel := context.WithCancel(context.Background()) // 利用context產生cancel方法
    valueCtx := context.WithValue(ctx, key, 1)
    go doStuff(valueCtx)
    time.Sleep(10 * time.Second)
    cancel()
}

func doStuff(ctx context.Context) {
	for {
	  select {
		case <-ctx.Done(): // cancel 時會觸發
			fmt.Println(ctx.Value(key))
			return
		default:
			//取出值
			var value int = ctx.Value(key).(int)
		}
	}
}

Context vs Channel

  1. Use context to cancel

    type Worker struct {
      Ctx context.Context
      Cancel context.CancelFunc
      Jobs chan Job
    }
    
    func (w *Worker) Run() {
      for {
        select {
        case <-w.Ctx.Done():
          return
        case j := <-w.Jobs:
          // Do some work
      }
    }
    
    go w.Run()
    w.Cancel()

    2. Use a kill channel to signal cancellation and a done channel to indicate that goroutine has been terminated.

    type Worker struct {
      Done chan struct{}
      Kill chan struct{}
      Jobs chan Job
    }
    
    func (w *Worker) Run() {
      defer func() {
        w.Done <- struct{}{}
      }
      for {
        select {
        case <-w.Kill:
          return
        case j := <-w.Jobs:
          // Do some work
      }
    }
    
    go w.Run()
    w.Kill <- struct{}{}

https://golang.org/pkg/context/
https://stackoverflow.com/q/54335907/4622645