如何正确配置goroutine限制?

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

How to properly configure the gorutine limit?

问题

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

func main() {
    checkMethod1 := true
    checkMethod2 := false
    checkMethod3 := true

    list := []string{"info1", "info2", "info3", "info5"}

    for _, value := range list {
        value := value
        if checkMethod1 {
            go func() {
                //使用value
                fmt.Println(value)
            }()
        }
        if checkMethod2 {
            go func() {
                //使用value
                fmt.Println(value)
            }()
        }
        if checkMethod3 {
            go func() {
                //使用value
                fmt.Println(value)
            }()
        }
    }
    //完成
    fmt.Println("All done")
}

我知道你可以将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.

func main() {
	checkMethod1 := true
	checkMethod2 := false
	checkMethod3 := true

	list := []string{"info1", "info2", "info3", "info5"}

	for _, value := range list {
		value := value
		if checkMethod1 {
			go func() {
				//use value
				fmt.Println(value)
			}()
		}
		if checkMethod2 {
			go func() {
				//use value
				fmt.Println(value)
			}()
		}
		if checkMethod3 {
			go func() {
				//use value
				fmt.Println(value)
			}()
		}
	}
	//finish
	fmt.Println("All done")
}

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:

m1 := make(chan struct{}, 10)
m2 := make(chan struct{}, 10)
m3 := make(chan struct{}, 10)
wg := sync.WaitGroup{}

for _, value := range list {
   value := value
   if checkMethod1 {
       m1 <- struct{}{}
       wg.Add(1)
       go func() {
           defer func() { 
              <-m1 
              wg.Done()
           }()
           // 进行工作
       }()
   }
   if checkMethod2 {
       m2 <- struct{}{}
       wg.Add(1)
       go func() {
           defer func() { 
               <-m2 
               wg.Done()
           }()
           // 进行工作
       }()
   }
   ...

  wg.Wait()
}

这段代码使用了带缓冲的通道(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:

m1:=make(chan struct{},10)
m2:=make(chan struct{},10)
m3:=make(chan struct{},10)
wg:=sync.WaitGroup{}

for _, value := range list {
   value := value
   if checkMethod1 {
       m1&lt;-struct{}{}
       wg.Add(1)
       go func() {
           defer func() { 
              &lt;-m1 
              wg.Done()
           }()
           // do work
       }()
   }
   if checkMethod2 {
       m2&lt;-struct{}{}
       wg.Add(1)
       go func() {
           defer func() { 
               &lt;-m2 
               wg.Done()
           }()
           // do work
       }()
   }
   ...

  wg.Wait()
}

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:

确定