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

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

count / display the number of active goroutines

问题

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

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

Playground链接

var element int

func deen(queue chan int) {
    element := <-queue
    fmt.Println("element is ", element)
    if element%2 == 0 {
        fmt.Println("new element is ", element)
        queue <- (element*100 + 11)
        queue <- (element*100 + 33)
    }
}

func main() {
    queue := make(chan int, 10)
    queue <- 1
    queue <- 2
    queue <- 3
    queue <- 0 
    for len(queue) != 0 {
        for i := 0; i < 2; i++ {
            go deen(queue)
        }
    }
    fmt.Scanln()
    fmt.Println("list is has len", len(queue)) //this must be 0
}
英文:

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

var element int

func deen(queue chan int) {

    element := &lt;-queue
    fmt.Println(&quot;element is &quot;, element)
    if element%2 == 0 {
        fmt.Println(&quot;new element is &quot;, element)
        queue &lt;- (element*100 + 11)
        queue &lt;- (element*100 + 33)
    }
}

func main() {
    queue := make(chan int, 10)
    queue &lt;- 1
    queue &lt;- 2
    queue &lt;- 3
    queue &lt;- 0 
    for len(queue) != 0 {
        for i := 0; i &lt; 2; i++ {
            go deen(queue)
        }
    }
    fmt.Scanln()
    fmt.Println(&quot;list is has len&quot;, len(queue)) //this must be 0

}    

答案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.

func deen(wg *sync.WaitGroup, queue chan int) {
	for element := range queue {
		fmt.Println(&quot;element is &quot;, element)
		if element%2 == 0 {
			fmt.Println(&quot;new element is &quot;, element)
			wg.Add(2)
			queue &lt;- (element*100 + 11)
			queue &lt;- (element*100 + 33)
		}
		wg.Done()
	}
}

func main() {
	var wg sync.WaitGroup
	queue := make(chan int, 10)
	queue &lt;- 1
	queue &lt;- 2
	queue &lt;- 3
	queue &lt;- 0
	for i := 0; i &lt; 4; i++ {
		wg.Add(1)
		go deen(&amp;wg, queue)
	}
	wg.Wait()
	close(queue)
	fmt.Println(&quot;list len&quot;, len(queue)) //this must be 0

}

<kbd>playground</kbd>

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

func deen(wg *sync.WaitGroup, queue chan int) {
	for element := range queue {
		wg.Done()
		fmt.Println(&quot;element is &quot;, element)
		if element%2 == 0 {
			fmt.Println(&quot;new element is &quot;, element)
			wg.Add(2)
			queue &lt;- (element*100 + 11)
			queue &lt;- (element*100 + 33)
		}
	}
}

func main() {
	var wg sync.WaitGroup
	queue := make(chan int, 10)
	queue &lt;- 1
	queue &lt;- 2
	queue &lt;- 3
	queue &lt;- 0
	for i := 0; i &lt; 4; i++ {
		wg.Add(1)
		go deen(&amp;wg, queue)
	}
	wg.Wait()
	close(queue)
	fmt.Println(&quot;list is has len&quot;, len(queue)) //this must be 0
}

<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:

确定