成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在 Go 語言中管理 Concurrency 的三種方式

開發 前端
本章會介紹幾種方式來帶大家認識并發,而這三種方式分別對應到三個不同的名詞:WaitGroup,Channel,及 Context。下面用簡單的范例帶大家了解。

相信大家踏入 Go 語言的世界,肯定是被強大的并發(Concurrency)所吸引,Go 語言用最簡單的關鍵字go就可以將任務丟到后臺處理,但是開發者怎么有效率的控制并發,這是入門 Go 語言必學的技能,本章會介紹幾種方式來帶大家認識并發,而這三種方式分別對應到三個不同的名詞:WaitGroup,Channel,及 Context。下面用簡單的范例帶大家了解。

[[337382]]

WaitGroup

先來了解有什么情境需要使用到 WaitGroup,假設您有兩臺機器需要同時上傳最新的代碼,兩臺機器分別上傳完成后,才能執行最后的重啟步驟。就像是把一個工作同時拆成好幾份同時一起做,可以減少時間,但是最后需要等到全部做完,才能執行下一步,這時候就需要用到 WaitGroup 才能做到。

  1. package main 
  2.  
  3. import ( 
  4.     "fmt" 
  5.     "sync" 
  6.  
  7. func main() { 
  8.     var wg sync.WaitGroup 
  9.     i := 0 
  10.     wg.Add(3) //task count wait to do 
  11.     go func() { 
  12.         defer wg.Done() // finish task1 
  13.         fmt.Println("goroutine 1 done"
  14.         i++ 
  15.     }() 
  16.     go func() { 
  17.         defer wg.Done() // finish task2 
  18.         fmt.Println("goroutine 2 done"
  19.         i++ 
  20.     }() 
  21.     go func() { 
  22.         defer wg.Done() // finish task3 
  23.         fmt.Println("goroutine 3 done"
  24.         i++ 
  25.     }() 
  26.     wg.Wait() // wait for tasks to be done 
  27.     fmt.Println("all goroutine done"
  28.     fmt.Println(i) 

Channel

另外一種實際的案例就是,我們需要主動通知一個 Goroutine 進行停止的動作。換句話說,當 App 啟動時,會在后臺跑一些監控程序,而當整個 App 需要停止前,需要發個 Notification 給后臺的監控程序,將其先停止,這時候就需要用到 Channel 來通知??聪孪旅孢@個例子:

  1. package main 
  2.  
  3. import ( 
  4.     "fmt" 
  5.     "time" 
  6.  
  7. func main() { 
  8.     exit := make(chan bool) 
  9.     go func() { 
  10.         for { 
  11.             select { 
  12.             case <-exit: 
  13.                 fmt.Println("Exit"
  14.                 return 
  15.             case <-time.After(2 * time.Second): 
  16.                 fmt.Println("Monitoring"
  17.             } 
  18.         } 
  19.     }() 
  20.     time.Sleep(5 * time.Second
  21.     fmt.Println("Notify Exit"
  22.     exit <- true //keep main goroutine alive 
  23.     time.Sleep(5 * time.Second

上面的例子可以發現,用了一個 Gogourtine 和 Channel 來控制。可以想像當后臺有無數個 Goroutine 的時候,我們就需要用多個 Channel 才能進行控制,也許 Goroutine 內又會產生 Goroutine,開發者這時候就會發現已經無法單純使用 Channel 來控制多個 Goroutine 了。這時候解決方式會是傳遞 Context。

Context

大家可以想像,今天有一個后臺任務 A,A 任務又產生了 B 任務,B 任務又產生了 C 任務,也就是可以按照此模式一直產生下去,假設中途我們需要停止 A 任務,而 A 又必須告訴 B 及 C 要一起停止,這時候通過 context 方式是最快的了。

 

  1. package main 
  2.  
  3. import ( 
  4.     "context" 
  5.     "fmt" 
  6.     "time" 
  7.  
  8. func foo(ctx context.Context, name string) { 
  9.     go bar(ctx, name) // A calls B 
  10.     for { 
  11.         select { 
  12.         case <-ctx.Done(): 
  13.             fmt.Println(name"A Exit"
  14.             return 
  15.         case <-time.After(1 * time.Second): 
  16.             fmt.Println(name"A do something"
  17.         } 
  18.     } 
  19.  
  20. func bar(ctx context.Context, name string) { 
  21.     for { 
  22.         select { 
  23.         case <-ctx.Done(): 
  24.             fmt.Println(name"B Exit"
  25.             return 
  26.         case <-time.After(2 * time.Second): 
  27.             fmt.Println(name"B do something"
  28.         } 
  29.     } 
  30.  
  31. func main() { 
  32.     ctx, cancel := context.WithCancel(context.Background()) 
  33.     go foo(ctx, "FooBar"
  34.     fmt.Println("client release connection, need to notify A, B exit"
  35.     time.Sleep(5 * time.Second
  36.     cancel() //mock client exit, and pass the signal, ctx.Done() gets the signal  time.Sleep(3 * time.Second
  37.     time.Sleep(3 * time.Second
  38.  
  39. package main 
  40.  
  41. import ( 
  42.     "context" 
  43.     "fmt" 
  44.     "time" 
  45.  
  46. func foo(ctx context.Context, name string) { 
  47.     go bar(ctx, name) // A calls B 
  48.     for { 
  49.         select { 
  50.         case <-ctx.Done(): 
  51.             fmt.Println(name"A Exit"
  52.             return 
  53.         case <-time.After(1 * time.Second): 
  54.             fmt.Println(name"A do something"
  55.         } 
  56.     } 
  57.  
  58. func bar(ctx context.Context, name string) { 
  59.     for { 
  60.         select { 
  61.         case <-ctx.Done(): 
  62.             fmt.Println(name"B Exit"
  63.             return 
  64.         case <-time.After(2 * time.Second): 
  65.             fmt.Println(name"B do something"
  66.         } 
  67.     } 
  68.  
  69. func main() { 
  70.     ctx, cancel := context.WithCancel(context.Background()) 
  71.     go foo(ctx, "FooBar"
  72.     fmt.Println("client release connection, need to notify A, B exit"
  73.     time.Sleep(5 * time.Second
  74.     cancel() //mock client exit, and pass the signal, ctx.Done() gets the signal  time.Sleep(3 * time.Second
  75.     time.Sleep(3 * time.Second

大家可以把 context 想成是一個 controller,可以隨時控制不確定個數的 Goroutine,由上往下,只要宣告context.WithCancel后,再任意時間點都可以通過cancel()來停止整個后臺服務。實際案例會用在當 App 需要重新啟動時,要先通知全部 goroutine 停止,正常停止后,才會重新啟動 App。

總結

根據不同的情境跟狀況來選擇不同的方式,做一個總結:

  • WaitGroup:需要將單一個工作分解成多個子任務,等到全部完成后,才能進行下一步,這時候用 WaitGroup 最適合了
  • Channel + Select:Channel 只能用在比較單純的 Goroutine 情況下,如果要管理多個 Goroutine,建議還是 走 context 會比較適合
  • Context:如果您想一次控制全部的 Goroutine,相信用 context 會是最適合不過的。

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2023-08-15 08:01:07

Go 語言排序

2022-05-31 16:00:46

Go 編程語言復制文件Go 標準庫

2012-07-17 09:16:16

SpringSSH

2023-12-19 16:43:01

2019-02-27 07:45:25

物聯網健康管理IOT

2024-05-10 08:36:40

Go語言對象

2023-03-28 07:46:46

go語言kubernetes

2019-08-28 09:04:02

Go語言Python操作系統

2021-11-05 21:33:28

Redis數據高并發

2019-11-20 18:52:24

物聯網智能照明智能恒溫器

2014-12-31 17:42:47

LBSAndroid地圖

2021-06-24 08:52:19

單點登錄代碼前端

2020-11-01 17:10:46

異步事件開發前端

2010-03-12 17:52:35

Python輸入方式

2022-06-26 06:31:25

Linux電子游戲

2014-04-09 09:32:24

Go并發

2024-07-08 09:03:31

2010-08-24 09:43:33

2023-08-22 07:05:34

PowerShellWindows

2018-04-02 14:29:18

Java多線程方式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 激情小说综合网 | 欧美亚洲国产日韩 | 日本黄色片免费在线观看 | 亚洲啪啪| 久久精品青青大伊人av | 黄色毛片免费看 | 九九亚洲精品 | 欧美日韩亚洲国产 | 欧美日韩在线精品 | 日韩一区二区三区精品 | 国产精品日韩高清伦字幕搜索 | 亚洲精品国产a久久久久久 午夜影院网站 | 人人人人干 | 午夜精品一区二区三区免费视频 | 久久一久久 | 亚洲一区二区电影在线观看 | 欧美一区永久视频免费观看 | 成人免费久久 | 超碰人人爱 | 中文字幕免费在线 | 亚洲精品小视频在线观看 | 亚洲午夜精品一区二区三区他趣 | 中文字幕亚洲视频 | 婷婷开心激情综合五月天 | 久久久久久国产 | 色综合久久天天综合网 | 99pao成人国产永久免费视频 | 波多野吉衣久久 | 91在线一区二区 | 99热精品国产| 黄色一级特级片 | 观看av| 天天综合永久入口 | 欧美性网 | 久久久精品一区二区 | 美女视频h | 亚洲午夜视频在线观看 | 国产免费拔擦拔擦8x高清 | 精品欧美在线观看 | 国产精品1区 | 亚洲国产成人精品女人久久久 |