91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言中怎么對Concurrency進行管理

發布時間:2021-07-20 15:26:01 來源:億速云 閱讀:135 作者:Leah 欄目:web開發

這篇文章給大家介紹 Go語言中怎么對Concurrency進行管理 ,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

WaitGroup

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

package main  import (     "fmt"     "sync" )  func main() {     var wg sync.WaitGroup     i := 0     wg.Add(3) //task count wait to do     go func() {         defer wg.Done() // finish task1         fmt.Println("goroutine 1 done")         i++     }()     go func() {         defer wg.Done() // finish task2         fmt.Println("goroutine 2 done")         i++     }()     go func() {         defer wg.Done() // finish task3         fmt.Println("goroutine 3 done")         i++     }()     wg.Wait() // wait for tasks to be done     fmt.Println("all goroutine done")     fmt.Println(i) }

Channel

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

package main  import (     "fmt"     "time" )  func main() {     exit := make(chan bool)     go func() {         for {             select {             case <-exit:                 fmt.Println("Exit")                 return             case <-time.After(2 * time.Second):                 fmt.Println("Monitoring")             }         }     }()     time.Sleep(5 * time.Second)     fmt.Println("Notify Exit")     exit <- true //keep main goroutine alive     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 方式是最快的了。

package main  import (     "context"     "fmt"     "time" )  func foo(ctx context.Context, name string) {     go bar(ctx, name) // A calls B     for {         select {         case <-ctx.Done():             fmt.Println(name, "A Exit")             return         case <-time.After(1 * time.Second):             fmt.Println(name, "A do something")         }     } }  func bar(ctx context.Context, name string) {     for {         select {         case <-ctx.Done():             fmt.Println(name, "B Exit")             return         case <-time.After(2 * time.Second):             fmt.Println(name, "B do something")         }     } }  func main() {     ctx, cancel := context.WithCancel(context.Background())     go foo(ctx, "FooBar")     fmt.Println("client release connection, need to notify A, B exit")     time.Sleep(5 * time.Second)     cancel() //mock client exit, and pass the signal, ctx.Done() gets the signal  time.Sleep(3 * time.Second)     time.Sleep(3 * time.Second) }  package main  import (     "context"     "fmt"     "time" )  func foo(ctx context.Context, name string) {     go bar(ctx, name) // A calls B     for {         select {         case <-ctx.Done():             fmt.Println(name, "A Exit")             return         case <-time.After(1 * time.Second):             fmt.Println(name, "A do something")         }     } }  func bar(ctx context.Context, name string) {     for {         select {         case <-ctx.Done():             fmt.Println(name, "B Exit")             return         case <-time.After(2 * time.Second):             fmt.Println(name, "B do something")         }     } }  func main() {     ctx, cancel := context.WithCancel(context.Background())     go foo(ctx, "FooBar")     fmt.Println("client release connection, need to notify A, B exit")     time.Sleep(5 * time.Second)     cancel() //mock client exit, and pass the signal, ctx.Done() gets the signal  time.Sleep(3 * time.Second)     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 會是最適合不過的。

關于 Go語言中怎么對Concurrency進行管理 就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

田东县| 涞水县| 巩义市| 万载县| 衡阳市| 西城区| 句容市| 红河县| 河南省| 武邑县| 正定县| 阿坝| 阿荣旗| 兖州市| 姚安县| 墨脱县| 象山县| 夏河县| 哈密市| 五大连池市| 东台市| 沧源| 太湖县| 左权县| 雅安市| 富宁县| 孟津县| 宁化县| 天祝| 定安县| 张北县| 石渠县| 霞浦县| 苍梧县| 清苑县| 西藏| 崇明县| 陵川县| 中西区| 东乡县| 泰顺县|