簡體   English   中英

管理動態goroutine池的最佳方法

[英]The best way to manage a dynamic goroutine pool

假設我有一個任務提供者 - 可讀渠道,它可能會也可能不會提供任務(取決於工作量)具體是因為幾個小時可能沒有工作然后可能會突然出現任務

我想讓我的goroutine池從1增長到N,其中N是工作出現時的最大並發數,然后自動折疊到1,其中goroutine的工作時間超過X秒以避免內存/ CPU浪費。

我本可以使用一個固定的游泳池,因為goroutines很便宜,但我不喜歡有數以千計的閑置goroutines我可能更好地使用這些資源(應該主要是ram但仍然)

折疊部分相當容易

for {
    timeoutTimer := time.NewTimer(WORKER_ROUTINE_TIMEOUT)

    select {
    case taskContext, isBatchRunning := <-runner.tasksCh:
        if !isBatchRunning {
            log.Print("task provider is closed, quit worker goroutine")
            return
        }

        runner.job.Process(&taskContext)
    case <-timeoutTimer.C:
        return
    }
}

但我不確定如何使池動態增長,即在哪種情況下產生一個新的

此池的優先級是能夠在增加的負載下快速做出反應並擴展到N(最大並發)goroutine,當工作負載減少時能夠最終崩潰到更合理的數字(1分鍾)

PS我看到了一個https://github.com/Jeffail/tunny包,但看起來它沒有類似於當前池大小的自適應縮放。 我錯過了什么嗎?

謝謝!

好吧,我不確定你需要一個游泳池。 Goroutines很快就會推出,你可能不需要一直保持准備就緒。

對於這個任務,我會使用一個簡單的信號量。 使用通道在Go中實現信號量非常容易。 你可以在這里看到我的個人例子。

您只需創建一個具有所需容量的信號量(這將是您允許的最大goroutines數),然后:

  1. 在goroutine開始時獲取信號量
  2. 在goroutine端發布它

就那么簡單。 並且不用擔心需要按需啟動它們; 它真的過度優化了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM