如何正确配置goroutine限制?

huangapple go评论121阅读模式
英文:

How to properly configure the gorutine limit?

问题

我有一个任务,如果选择工作,将执行三个函数。我想限制每个函数的goroutine数量。例如,每个函数最多只能同时运行10个goroutine。

  1. func main() {
  2. checkMethod1 := true
  3. checkMethod2 := false
  4. checkMethod3 := true
  5. list := []string{"info1", "info2", "info3", "info5"}
  6. for _, value := range list {
  7. value := value
  8. if checkMethod1 {
  9. go func() {
  10. //使用value
  11. fmt.Println(value)
  12. }()
  13. }
  14. if checkMethod2 {
  15. go func() {
  16. //使用value
  17. fmt.Println(value)
  18. }()
  19. }
  20. if checkMethod3 {
  21. go func() {
  22. //使用value
  23. fmt.Println(value)
  24. }()
  25. }
  26. }
  27. //完成
  28. fmt.Println("All done")
  29. }

我知道你可以将goroutine数量限制为一个工作池。但是,如果我创建一个具有10个goroutine限制的工作池,那个数字会被分成3个任务,而我需要每个函数都有10个goroutine。

我可以创建3个工作池,但这对我来说似乎不可行。

我想使用这个库来创建工作池:https://github.com/sourcegraph/conc

英文:

I have a task where three functions are performed if they are selected to work. I want to limit the number of horoutines per function. For example so that each of them has only a maximum of 10 goroutines running.

  1. func main() {
  2. checkMethod1 := true
  3. checkMethod2 := false
  4. checkMethod3 := true
  5. list := []string{"info1", "info2", "info3", "info5"}
  6. for _, value := range list {
  7. value := value
  8. if checkMethod1 {
  9. go func() {
  10. //use value
  11. fmt.Println(value)
  12. }()
  13. }
  14. if checkMethod2 {
  15. go func() {
  16. //use value
  17. fmt.Println(value)
  18. }()
  19. }
  20. if checkMethod3 {
  21. go func() {
  22. //use value
  23. fmt.Println(value)
  24. }()
  25. }
  26. }
  27. //finish
  28. fmt.Println("All done")
  29. }

I know that you can limit the number of goroutines to a pool of workers. But if I make one pool of workers with a limit of 10 goroutines, that number is divided by 3 tasks, and I need each function to have 10 goroutines.

I could create 3 pools, but that doesn't seem like a workable way to me.

I would like to use this library to create working pools: https://github.com/sourcegraph/conc

答案1

得分: 2

这是一种方法:为每个选项使用带缓冲的通道,以便可以限制活动的 goroutine:

  1. m1 := make(chan struct{}, 10)
  2. m2 := make(chan struct{}, 10)
  3. m3 := make(chan struct{}, 10)
  4. wg := sync.WaitGroup{}
  5. for _, value := range list {
  6. value := value
  7. if checkMethod1 {
  8. m1 <- struct{}{}
  9. wg.Add(1)
  10. go func() {
  11. defer func() {
  12. <-m1
  13. wg.Done()
  14. }()
  15. // 进行工作
  16. }()
  17. }
  18. if checkMethod2 {
  19. m2 <- struct{}{}
  20. wg.Add(1)
  21. go func() {
  22. defer func() {
  23. <-m2
  24. wg.Done()
  25. }()
  26. // 进行工作
  27. }()
  28. }
  29. ...
  30. wg.Wait()
  31. }

这段代码使用了带缓冲的通道(buffered channel)来限制同时活跃的 goroutine 数量。通过向通道发送信号(m1 <- struct{}{}),可以控制 goroutine 的启动。在每个 goroutine 结束时,通过从通道接收信号(<-m1)来释放一个位置,以便新的 goroutine 可以启动。sync.WaitGroup 用于等待所有 goroutine 完成工作。

英文:

Here's a way to do it: use a buffered channel for each option, so you can limit active goroutines:

  1. m1:=make(chan struct{},10)
  2. m2:=make(chan struct{},10)
  3. m3:=make(chan struct{},10)
  4. wg:=sync.WaitGroup{}
  5. for _, value := range list {
  6. value := value
  7. if checkMethod1 {
  8. m1&lt;-struct{}{}
  9. wg.Add(1)
  10. go func() {
  11. defer func() {
  12. &lt;-m1
  13. wg.Done()
  14. }()
  15. // do work
  16. }()
  17. }
  18. if checkMethod2 {
  19. m2&lt;-struct{}{}
  20. wg.Add(1)
  21. go func() {
  22. defer func() {
  23. &lt;-m2
  24. wg.Done()
  25. }()
  26. // do work
  27. }()
  28. }
  29. ...
  30. wg.Wait()
  31. }

huangapple
  • 本文由 发表于 2023年4月23日 05:00:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76081910.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定