亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

Go并發編程實踐

2020-04-01 19:07:28
字體:
來源:轉載
供稿:網友

前言

并發編程一直是Golang區別與其他語言的很大優勢,也是實際工作場景中經常遇到的。近日筆者在組內分享了我們常見的并發場景,及代碼示例,以期望大家能在遇到相同場景下,能快速的想到解決方案,或者是拿這些方案與自己實現的比較,取長補短?,F整理出來與大家共享。

簡單并發場景

很多時候,我們只想并發的做一件事情,比如測試某個接口的是否支持并發。那么我們就可以這么做:

func RunScenario1() {    count := 10    var wg sync.WaitGroup    for i := 0; i < count; i++ {       wg.Add(1)       go func(index int) {           defer wg.Done()           doSomething(index)       }(i)    }    wg.Wait()}

使用goroutine來實現異步,使用WaitGroup來等待所有goroutine結束。這里要注意的是要正確釋放WaitGroup的counter(在goroutine里調用Done()方法)。

但此種方式有個弊端,就是當goroutine的量過多時,很容易消耗完客戶端的資源,導致程序表現不佳。

規定時間內的持續并發模型

我們仍然以測試某個后端API接口為例,如果我們想知道這個接口在持續高并發情況下是否有句柄泄露,這種情況該如何測試呢?

這種時候,我們需要能控制時間的高并發模型:

func RunScenario2() {  timeout := time.Now().Add(time.Second * time.Duration(10))  n := runtime.NumCPU()  waitForAll := make(chan struct{})  done := make(chan struct{})  concurrentCount := make(chan struct{}, n)  for i := 0; i < n; i++ {    concurrentCount <- struct{}{}  }  go func() {    for time.Now().Before(timeout) {      <-done      concurrentCount <- struct{}{}    }    waitForAll <- struct{}{}  }()  go func() {    for {      <-concurrentCount      go func() {        doSomething(rand.Intn(n))        done <- struct{}{}      }()    }  }()  <-waitForAll}

上面的代碼里,我們通過一個buffered channel來控制并發的數量(concurrentCount),然后另起一個channel來周期性的發起新的任務,而控制的條件就是 time.Now().Before(timeout),這樣當超過規定的時間,waitForAll 就會得到信號,而使整個程序退出。

這是一種實現方式,那么還有其他的方式沒?我們接著往下看。

基于大數據量的并發模型

前面說的基于時間的并發模型,那如果只知道數據量很大,但是具體結束時間不確定,該怎么辦呢?

比如,客戶給了個幾TB的文件列表,要求把這些文件從存儲里刪除。再比如,實現個爬蟲去爬某些網站的所有內容。

而解決此類問題,最常見的就是使用工作池模式了(Worker Pool)。以刪文件為例,我們可以簡單這樣來處理:

Go并發

Jobs - 可以從文件列表里讀取文件,初始化為任務,然后發給worker
Worker - 拿到任務開始做事
Collector - 收集worker處理后的結果
Worker Pool - 控制并發的數量

雖然這只是個簡單Worker Pool模型,但已經能滿足我們的需求:

func RunScenario3() {    numOfConcurrency := runtime.NumCPU()    taskTool := 10    jobs := make(chan int, taskTool)    results := make(chan int, taskTool)    var wg sync.WaitGroup    // workExample    workExampleFunc := func(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {       defer wg.Done()       for job := range jobs {           res := job * 2           fmt.Printf("Worker %d do things, produce result %d /n", id, res)           time.Sleep(time.Millisecond * time.Duration(100))           results <- res       }    }    for i := 0; i < numOfConcurrency; i++ {       wg.Add(1)       go workExampleFunc(i, jobs, results, &wg)    }    totalTasks := 100 // 本例就要從文件列表里讀取    wg.Add(1)    go func() {       defer wg.Done()       for i := 0; i < totalTasks; i++ {           n := <-results           fmt.Printf("Got results %d /n", n)       }       close(results)    }()    for i := 0; i < totalTasks; i++ {       jobs <- i    }    close(jobs)    wg.Wait()}

在Go里,分發任務,收集結果,我們可以都交給Channel來實現。從實現上更加的簡潔。

仔細看會發現,本模型也是適用于按時間來控制并發。只要把totalTask的遍歷換成時間控制就好了。

等待異步任務執行結果

goroutine和channel的組合在實際編程時經常會用到,而加上Select更是無往而不利。

func RunScenario4() {    sth := make(chan string)    result := make(chan string)    go func() {       id := rand.Intn(100)       for {           sth <- doSomething(id)       }    }()    go func() {       for {           result <- takeSomthing(<-sth)       }    }()    select {    case c := <-result:       fmt.Printf("Got result %s ", c)    case <-time.After(time.Duration(30 * time.Second)):       fmt.Errorf("指定時間內都沒有得到結果")    }}

在select的case情況,加上time.After()模型可以讓我們在一定時間范圍內等待異步任務結果,防止程序卡死。

定時反饋異步任務結果

上面我們說到持續的壓測某后端API,但并未實時收集結果。而很多時候對于性能測試場景,實時的統計吞吐率,成功率是非常有必要的。

func RunScenario5() {  concurrencyCount := runtime.NumCPU()  for i := 0; i < concurrencyCount; i++ {    go func(index int) {      for {        doUploadMock()      }    }(i)  }  t := time.NewTicker(time.Second)  for {    select {    case <-t.C:      // 計算并打印實時數據    }  } }

這種場景就需要使用到Ticker,且上面的Example模型還能控制并發數量,也是非常實用的方式。

知識點總結

上面我們共提到了五種并發模式:

  • 簡單并發模型
  • 規定時間內的持續并發模型
  • 基于大數據量的持續并發模型
  • 等待異步任務結果模型
  • 定時反饋異步任務結果模型

 

歸納下來其核心就是使用了Go的幾個知識點:Goroutine, Channel, Select, Time, Timer/Ticker, WaitGroup. 若是對這些不清楚,可以自行Google之。

另完整的Example 代碼可以參考這里:https://github.com/jichangjun/golearn/blob/master/src/carlji.com/experiments/concurrency/main.go

使用方式: go run main.go <場景>

比如 :

Go并發

參考文檔

https://github.com/golang/go/wiki/LearnConcurrency
這篇是Google官方推薦學習Go并發的資料,從初學者到進階,內容非常豐富,且權威。

Contact me ?

Email: jinsdu@outlook.com

Blog: http://www.cnblogs.com/jinsdu/

Github: https://github.com/CarlJi

 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91九色综合久久| 国产日韩精品综合网站| 在线亚洲男人天堂| 久久在精品线影院精品国产| 欧美疯狂xxxx大交乱88av| 北条麻妃99精品青青久久| 亚洲天堂第二页| 最近2019年手机中文字幕| 国产精品www| 日本久久久久久久| 在线精品国产欧美| 国产a∨精品一区二区三区不卡| 欧美性猛交xxxxx免费看| 国内揄拍国内精品| 91亚洲精品一区| 亚洲欧洲偷拍精品| 欧美电影免费看| 久久久久久有精品国产| 久久久成人av| 一色桃子一区二区| 国产一区二中文字幕在线看| 高清一区二区三区四区五区| 55夜色66夜色国产精品视频| 国产精品爽爽爽爽爽爽在线观看| 91色中文字幕| 夜色77av精品影院| 国产亚洲视频中文字幕视频| 亚洲精品日韩丝袜精品| 国产亚洲激情在线| 精品国偷自产在线视频99| 91香蕉嫩草影院入口| 亚洲成人三级在线| 久久国产精品久久久| 欧美综合国产精品久久丁香| 欧美极品少妇与黑人| 日韩在线精品视频| 亚洲人永久免费| 九九九热精品免费视频观看网站| 亚洲性生活视频在线观看| 在线观看91久久久久久| 青草青草久热精品视频在线观看| 欧美日本啪啪无遮挡网站| 欧美自拍视频在线| 国产欧美日韩专区发布| 亚洲tv在线观看| 久久久女人电视剧免费播放下载| 精品一区电影国产| 日韩国产精品亚洲а∨天堂免| 91麻豆桃色免费看| 777777777亚洲妇女| 国产欧美一区二区三区久久| 91精品国产高清自在线看超| 国产91av在线| 午夜精品一区二区三区av| 久久久久久久一| 国产一区二区三区网站| 性金发美女69hd大尺寸| 国产精品999999| 欧美成人三级视频网站| 亚洲欧美精品中文字幕在线| 怡红院精品视频| 欧美精品一二区| 久久频这里精品99香蕉| 欧美在线一区二区视频| 91精品在线观| 成人黄色短视频在线观看| 欧美精品做受xxx性少妇| 中文字幕亚洲无线码a| 亚洲成人三级在线| 亚洲精品成人久久| 国产精彩精品视频| 亚洲开心激情网| 亚洲一区亚洲二区亚洲三区| 亚洲欧美中文日韩v在线观看| 亚洲天堂av在线免费观看| 奇米一区二区三区四区久久| 中文字幕一区二区精品| 91精品免费视频| 国产精品国产三级国产aⅴ9色| 国产精品mp4| 操人视频在线观看欧美| 精品精品国产国产自在线| 日韩亚洲欧美中文在线| 精品露脸国产偷人在视频| 久久99国产精品久久久久久久久| 欧美激情精品久久久久久变态| 精品国产自在精品国产浪潮| 亚洲精品美女网站| 国产91精品黑色丝袜高跟鞋| 欧美精品免费播放| 91精品国产乱码久久久久久久久| 久久精品国亚洲| 国产精品99久久久久久www| 亚洲欧美日韩在线高清直播| 国产精品视频永久免费播放| 国产一区二区三区在线视频| 青青草精品毛片| 国产一区欧美二区三区| 成人久久久久爱| 一本大道香蕉久在线播放29| 久久久久久免费精品| 日韩av综合中文字幕| 亚洲精品第一页| 欧美精品免费看| 欧美激情伊人电影| 亚洲激情久久久| 最近中文字幕日韩精品| 26uuu国产精品视频| 欧美日韩免费看| 国产精品自产拍在线观| 色婷婷综合久久久久中文字幕1| 777777777亚洲妇女| 91精品国产沙发| 久久综合免费视频| 亚洲成人久久久| 精品电影在线观看| 成人免费黄色网| 亚洲精品一区二区久| 91高清免费在线观看| 亚洲欧美一区二区精品久久久| 青青草一区二区| 丁香五六月婷婷久久激情| 日韩最新av在线| 韩日精品中文字幕| 久久亚洲国产精品| 亚洲欧美日本伦理| 亚洲午夜精品久久久久久性色| 日韩欧美精品免费在线| 亚洲jizzjizz日本少妇| 91高清视频在线免费观看| 热久久免费国产视频| zzjj国产精品一区二区| 国产91色在线免费| 国产在线精品播放| 国产精品久久视频| 久久影院在线观看| 欧美色另类天堂2015| 亚洲国产欧美日韩精品| 欧美激情免费看| 精品久久久国产精品999| 国产精品久久久久久久久久久久久| 2023亚洲男人天堂| 日韩的一区二区| 亚洲日韩中文字幕在线播放| 中文字幕久热精品视频在线| 亚洲精品自拍视频| 亚洲国产成人爱av在线播放| 色综合男人天堂| 精品国产一区二区三区在线观看| 81精品国产乱码久久久久久| 久久99久国产精品黄毛片入口| 国产精品无码专区在线观看| 中文字幕亚洲综合久久筱田步美| 国产精品网站入口| 日韩中文字幕视频| 国产亚洲视频在线观看| 国产精品精品一区二区三区午夜版| 97欧美精品一区二区三区| 成人信息集中地欧美| 免费av在线一区| 亚洲人成网站色ww在线| 国产精品成人国产乱一区| 欧美在线亚洲一区| 成人激情视频在线播放|