欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang實現(xiàn)并發(fā)控制的方法和技巧

 更新時間:2024年03月05日 09:40:55   作者:嘻嘻愛編碼  
golang 是一門支持并發(fā)的編程語言,它提供了 goroutine 和 channel 等強大的特性,讓我們可以輕松地創(chuàng)建和管理多個執(zhí)行單元,實現(xiàn)高效的任務處理,在本文中,我們將介紹一些 golang 的并發(fā)控制的方法和技巧,希望對你有所幫助

前言

golang 是一門支持并發(fā)的編程語言,它提供了 goroutine 和 channel 等強大的特性,讓我們可以輕松地創(chuàng)建和管理多個執(zhí)行單元,實現(xiàn)高效的任務處理。但是,并發(fā)也帶來了一些挑戰(zhàn),比如如何控制 goroutine 的數(shù)量,如何避免資源競爭,如何保證數(shù)據(jù)的一致性等。在本文中,我們將介紹一些 golang 的并發(fā)控制的方法和技巧,希望對你有所幫助。

為什么要控制 goroutine 的數(shù)量

goroutine 是 golang 中最基本的執(zhí)行單元,它是一種輕量級的線程,可以在一個或多個系統(tǒng)線程上運行。goroutine 的創(chuàng)建和調(diào)度都不需要進入內(nèi)核,因此開銷很小,我們可以輕松地創(chuàng)建上百萬個而不會導致系統(tǒng)資源耗盡。那么,我們是不是可以隨心所欲地使用 goroutine,而不用擔心它的數(shù)量呢?

答案是否定的。雖然 goroutine 很輕量,但它也不是免費的,它也會占用一定的內(nèi)存空間,每個 goroutine 至少需要 2KB 的棧空間,如果 goroutine 的數(shù)量過多,就會導致內(nèi)存不足,甚至觸發(fā)頻繁的垃圾回收,影響程序的性能。另外,goroutine 也會消耗 CPU 的時間片,如果 goroutine 的數(shù)量超過 CPU 的核心數(shù),就會導致上下文切換,增加 CPU 的負擔。因此,我們在使用 goroutine 的時候,需要根據(jù)實際的場景和需求,合理地控制 goroutine 的數(shù)量,避免過度并發(fā)。

如何控制 goroutine 的數(shù)量

那么,我們?nèi)绾慰刂?goroutine 的數(shù)量呢?有沒有什么通用的方法或者技巧呢?其實,golang 本身就提供了一些并發(fā)控制的機制,比如 channel 和 sync 包,我們可以利用它們來實現(xiàn) goroutine 的數(shù)量限制。下面,我們就來看一些具體的例子。

利用 channel 的緩沖區(qū)

channel 是 golang 中實現(xiàn)并發(fā)通信的重要工具,它可以在不同的 goroutine 之間傳遞數(shù)據(jù),實現(xiàn)同步和協(xié)作。channel 有兩種類型,一種是無緩沖的 channel,另一種是有緩沖的 channel。無緩沖的 channel 是同步的,發(fā)送和接收操作必須同時發(fā)生,否則會阻塞。有緩沖的 channel 是異步的,它有一個固定大小的緩沖區(qū),可以存儲一定數(shù)量的數(shù)據(jù),發(fā)送操作只有在緩沖區(qū)滿的時候才會阻塞,接收操作只有在緩沖區(qū)空的時候才會阻塞。

我們可以利用有緩沖的 channel 的特性,來實現(xiàn) goroutine 的數(shù)量限制。具體的思路是,我們創(chuàng)建一個有緩沖的 channel,緩沖區(qū)的大小就是我們想要限制的 goroutine 的數(shù)量。然后,我們在啟動一個 goroutine 之前,先向 channel 發(fā)送一個空結(jié)構體,如果 channel 滿了,就會阻塞,直到有其他 goroutine 退出,從 channel 接收一個空結(jié)構體,釋放緩沖區(qū)。這樣,我們就可以保證同時運行的 goroutine 的數(shù)量不會超過 channel 的緩沖區(qū)大小。下面是一個簡單的例子:

package main
 
import (
    "fmt"
    "sync"
    "time"
)
 
func main() {
    var wg sync.WaitGroup
    ch := make(chan struct{}, 3) // 創(chuàng)建一個緩沖區(qū)大小為 3 的 channel
    for i := 0; i < 10; i++ {
        ch <- struct{}{} // 向 channel 發(fā)送一個空結(jié)構體,如果 channel 滿了,就會阻塞
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            fmt.Println(i) // 做一些業(yè)務邏輯處理
            time.Sleep(time.Second)
            <-ch // 從 channel 接收一個空結(jié)構體,釋放緩沖區(qū)
        }(i)
    }
    wg.Wait()
}

運行結(jié)果如下:

0
1
2
3
4
5
6
7
8
9

從結(jié)果中可以看到,每秒鐘只并發(fā)執(zhí)行了 3 個 goroutine,達到了我們的目的。這種方法的優(yōu)點是簡單易用,缺點是需要手動管理 channel 的發(fā)送和接收,如果忘記了,就會導致 goroutine 泄露或者死鎖。

利用 sync 包

sync 包是 golang 提供的一個并發(fā)同步的包,它提供了一些常用的同步原語,比如互斥鎖,條件變量,等待組等。其中,等待組(WaitGroup)是一個非常有用的工具,它可以用來等待一組 goroutine 的完成。WaitGroup 對象內(nèi)部有一個計數(shù)器,最初從 0 開始,它有三個方法:Add,Done,Wait。Add 方法用來增加計數(shù)器的值,Done 方法用來減少計數(shù)器的值,Wait 方法用來阻塞,直到計數(shù)器的值為 0。

我們可以利用 WaitGroup 來實現(xiàn) goroutine 的數(shù)量限制。具體的思路是,我們創(chuàng)建一個 WaitGroup 對象,然后在啟動一個 goroutine 之前,先調(diào)用 Add 方法,增加計數(shù)器的值,如果計數(shù)器的值達到了我們想要限制的 goroutine 的數(shù)量,就會阻塞,直到有其他 goroutine 結(jié)束,調(diào)用 Done 方法,減少計數(shù)器的值,解除阻塞。這樣,我們就可以保證同時運行的 goroutine 的數(shù)量不會超過我們設定的值。下面是一個簡單的例子:

package main
 
import (
    "fmt"
    "sync"
    "time"
)
 
func main() {
    var wg sync.WaitGroup
    limit := 3 // 限制 goroutine 的數(shù)量為 3
    for i := 0; i < 10; i++ {
        wg.Add(1) // 增加計數(shù)器的值,如果計數(shù)器的值達到 limit,就會阻塞
        go func(i int) {
            defer wg.Done()
            fmt.Println(i) // 做一些業(yè)務邏輯處理
            time.Sleep(time.Second)
        }(i)
        if i >= limit {
            wg.Wait() // 等待其他 goroutine 結(jié)束,減少計數(shù)器的值,解除阻塞
        }
    }
    wg.Wait()
}

運行結(jié)果如下:

0
1
2
3
4
5
6
7
8
9

從結(jié)果中可以看到,每秒鐘只并發(fā)執(zhí)行了 3 個 goroutine,達到了我們的目的。這種方法的優(yōu)點是不需要額外的 channel,缺點是需要手動管理 WaitGroup 的 Add 和 Done 方法,如果忘記了,也會導致 goroutine 泄露或者死鎖。

總結(jié)

在本文中,我們介紹了為什么要控制 goroutine 的數(shù)量,以及如何使用 golang 的 channel 和 sync 包來實現(xiàn) goroutine 的數(shù)量限制。這些方法都是基于 golang 的并發(fā)特性,不需要引入第三方的庫或者框架,可以方便地應用在實際的項目中。當然,這些方法并不是唯一的,也不一定是最優(yōu)的,你可以根據(jù)你的具體的場景和需求,選擇合適的方法,或者自己設計更好的方法,來實現(xiàn) goroutine 的數(shù)量限制。

以上就是golang實現(xiàn)并發(fā)控制的方法和技巧的詳細內(nèi)容,更多關于golang并發(fā)控制的資料請關注腳本之家其它相關文章!

相關文章

  • go語言環(huán)境變量設置全過程

    go語言環(huán)境變量設置全過程

    這篇文章主要介紹了go語言環(huán)境變量設置全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Golang并發(fā)繞不開的重要組件之Goroutine詳解

    Golang并發(fā)繞不開的重要組件之Goroutine詳解

    Goroutine、Channel、Context、Sync都是Golang并發(fā)編程中的幾個重要組件,這篇文中主要為大家介紹了Goroutine的相關知識,需要的可以參考一下
    2023-06-06
  • Golang加權輪詢負載均衡的實現(xiàn)

    Golang加權輪詢負載均衡的實現(xiàn)

    負載均衡器在向后端服務分發(fā)流量負載時可以使用幾種策略。本文主要介紹了Golang加權輪詢負載均衡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Go設計模式之單例模式圖文詳解

    Go設計模式之單例模式圖文詳解

    單例模式是一種創(chuàng)建型設計模式,讓你能夠保證一個類只有一個實例,并提供一個訪問該實例的全局節(jié)點,本文就通過圖文給大家介紹一下Go的單例模式,需要的朋友可以參考下
    2023-07-07
  • golang 常用定時任務匯總

    golang 常用定時任務匯總

    這篇文章主要介紹了golang 常用定時任務匯總,golang利用goroutine外加github.com/gorhill/cronexpr庫就可實現(xiàn)定時任務,具體代碼介紹,需要的小伙伴可以參考一下
    2022-09-09
  • Go語言并發(fā)之Select多路選擇操作符用法詳解

    Go語言并發(fā)之Select多路選擇操作符用法詳解

    Go?語言借用多路復用的概念,提供了?select?關鍵字,用于多路監(jiān)聽多個通道,本文就來和大家聊聊Go語言中Select多路選擇操作符的具體用法,希望對大家有所幫助
    2023-06-06
  • Gin框架使用panic處理中間件問題詳解

    Gin框架使用panic處理中間件問題詳解

    這篇文章主要介紹了Gin框架使用panic處理中間件問題,在 Gin 框架中,錯誤處理和 panic 處理是非常重要的功能。當處理 HTTP 請求時,可能會出現(xiàn)各種各樣的錯誤,例如數(shù)據(jù)庫連接錯誤、網(wǎng)絡錯誤、權限問題等等
    2023-04-04
  • 淺談Go語言的空標示符

    淺談Go語言的空標示符

    本文通過文字及實例介紹了Go語言的空標示符,對此有不明白的朋友可以參考學習,下面一起來看看吧。
    2016-08-08
  • go grpc安裝使用教程

    go grpc安裝使用教程

    gRPC是由Google主導開發(fā)的RPC框架,使用HTTP/2協(xié)議并用ProtoBuf作為序列化工具。這篇文章主要介紹了go grpc安裝使用教程,需要的朋友可以參考下
    2018-02-02
  • Go語言清除文件中空行的方法

    Go語言清除文件中空行的方法

    這篇文章主要介紹了Go語言清除文件中空行的方法,實例分析了Go語言針對文件的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02

最新評論