计算/显示活动goroutine的数量。

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

count / display the number of active goroutines

问题

我有一个队列和一个既可以出队又可以入队的函数。只要列表中有内容,我希望确保有适量的goroutine在队列上运行。

这是我正在使用的代码,但我想知道是否有一种方法可以打印当前活动的goroutine数量。

Playground链接

  1. var element int
  2. func deen(queue chan int) {
  3. element := <-queue
  4. fmt.Println("element is ", element)
  5. if element%2 == 0 {
  6. fmt.Println("new element is ", element)
  7. queue <- (element*100 + 11)
  8. queue <- (element*100 + 33)
  9. }
  10. }
  11. func main() {
  12. queue := make(chan int, 10)
  13. queue <- 1
  14. queue <- 2
  15. queue <- 3
  16. queue <- 0
  17. for len(queue) != 0 {
  18. for i := 0; i < 2; i++ {
  19. go deen(queue)
  20. }
  21. }
  22. fmt.Scanln()
  23. fmt.Println("list is has len", len(queue)) //this must be 0
  24. }
英文:

I have a queue and a function that does both dequeueing and enqueueing. I want to make sure that the right amount of goroutines operate on the queue, as long as there is something in the list.

This is the code I am using, but I was wondering if there is a way of printing the amount of currently active goroutines

Link to playground

  1. var element int
  2. func deen(queue chan int) {
  3. element := &lt;-queue
  4. fmt.Println(&quot;element is &quot;, element)
  5. if element%2 == 0 {
  6. fmt.Println(&quot;new element is &quot;, element)
  7. queue &lt;- (element*100 + 11)
  8. queue &lt;- (element*100 + 33)
  9. }
  10. }
  11. func main() {
  12. queue := make(chan int, 10)
  13. queue &lt;- 1
  14. queue &lt;- 2
  15. queue &lt;- 3
  16. queue &lt;- 0
  17. for len(queue) != 0 {
  18. for i := 0; i &lt; 2; i++ {
  19. go deen(queue)
  20. }
  21. }
  22. fmt.Scanln()
  23. fmt.Println(&quot;list is has len&quot;, len(queue)) //this must be 0
  24. }

答案1

得分: 25

这是一段关于使用Go语言中的sync.WaitGroup的代码示例。它解决了在循环中创建大量goroutine和浪费CPU周期的问题。

代码中定义了一个名为deen的函数,它接受一个sync.WaitGroup类型的指针和一个int类型的通道作为参数。在deen函数中,通过range循环从通道中读取元素,并对元素进行处理。如果元素是偶数,它会创建两个新的元素,并将它们发送到通道中。然后,通过调用wg.Done()来表示一个goroutine的工作已经完成。

在main函数中,首先创建了一个sync.WaitGroup类型的变量wg和一个容量为10的int类型通道queue。然后,将一些初始元素发送到通道中。接下来,使用for循环创建了4个goroutine,并将它们启动。每个goroutine都调用deen函数,并传递了wg和queue作为参数。最后,通过调用wg.Wait()等待所有的goroutine完成工作,然后关闭通道并打印队列的长度。

这段代码的目的是确保最后打印的队列长度为0,以验证所有的goroutine都已经完成工作。

你可以在这里找到完整的代码示例:playground

另外,还提供了一个旧版本的代码,其中存在竞态条件。在这个版本中,wg.Done()的调用位置不正确,可能导致goroutine计数不正确。这个问题在新版本的代码中得到了修复。

你可以在这里找到旧版本的代码:playground

英文:

There's runtime.NumGoroutine but you're approaching this wrong.

  1. Your loops will keep spawning goroutines.
  2. this will unnecessarily burn cpu cycles because of the for loop.

One approach is to use a sync.WaitGroup.

  1. func deen(wg *sync.WaitGroup, queue chan int) {
  2. for element := range queue {
  3. fmt.Println(&quot;element is &quot;, element)
  4. if element%2 == 0 {
  5. fmt.Println(&quot;new element is &quot;, element)
  6. wg.Add(2)
  7. queue &lt;- (element*100 + 11)
  8. queue &lt;- (element*100 + 33)
  9. }
  10. wg.Done()
  11. }
  12. }
  13. func main() {
  14. var wg sync.WaitGroup
  15. queue := make(chan int, 10)
  16. queue &lt;- 1
  17. queue &lt;- 2
  18. queue &lt;- 3
  19. queue &lt;- 0
  20. for i := 0; i &lt; 4; i++ {
  21. wg.Add(1)
  22. go deen(&amp;wg, queue)
  23. }
  24. wg.Wait()
  25. close(queue)
  26. fmt.Println(&quot;list len&quot;, len(queue)) //this must be 0
  27. }

<kbd>playground</kbd>

--- old buggy version with a race in it ---

  1. func deen(wg *sync.WaitGroup, queue chan int) {
  2. for element := range queue {
  3. wg.Done()
  4. fmt.Println(&quot;element is &quot;, element)
  5. if element%2 == 0 {
  6. fmt.Println(&quot;new element is &quot;, element)
  7. wg.Add(2)
  8. queue &lt;- (element*100 + 11)
  9. queue &lt;- (element*100 + 33)
  10. }
  11. }
  12. }
  13. func main() {
  14. var wg sync.WaitGroup
  15. queue := make(chan int, 10)
  16. queue &lt;- 1
  17. queue &lt;- 2
  18. queue &lt;- 3
  19. queue &lt;- 0
  20. for i := 0; i &lt; 4; i++ {
  21. wg.Add(1)
  22. go deen(&amp;wg, queue)
  23. }
  24. wg.Wait()
  25. close(queue)
  26. fmt.Println(&quot;list is has len&quot;, len(queue)) //this must be 0
  27. }

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2014年9月26日 10:18:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/26051059.html
匿名

发表评论

匿名网友

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

确定