Go语言中的Goroutines并发示例之旅

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

A Tour of Go example on Goroutines concurrency

问题

我是你的中文翻译助手,以下是翻译好的内容:

我对Go语言还不熟悉,在这里学习:https://tour.golang.org/concurrency/1

当我运行https://play.golang.org/p/9JvbtSuv5o时,结果是:

world
hello
hello

所以我添加了sync.WaitGroup:https://play.golang.org/p/vjdhnDssGk

package main

import (
	"fmt"
	"sync"
	"time"
)

var w sync.WaitGroup

func say(s string) {
	for i := 0; i < 2; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	w.Done()
}

func main() {
	w.Add(1)
	go say("world")
	say("hello")
	w.Wait()
}

但结果仍然相同:

world
hello
hello

我的代码有什么问题?

请帮忙看看,谢谢你的帮助。

英文:

I'm new to the Go Language, and learning here:
https://tour.golang.org/concurrency/1

When I run https://play.golang.org/p/9JvbtSuv5o the result is:

world
hello
hello

So Added sync.WaitGroup: https://play.golang.org/p/vjdhnDssGk

<!-- language: lang-golang -->

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

var w sync.WaitGroup

func say(s string) {
	for i := 0; i &lt; 2; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	w.Done()
}

func main() {
	w.Add(1)
	go say(&quot;world&quot;)
	say(&quot;hello&quot;)
	w.Wait()
}

But the result is same:

world
hello
hello

What is wrong with my code?

Please help,
Thank you for your help.

答案1

得分: 0

w.Done() 函数会减少 WaitGroup 计数器的值。所以你的代码有时会出现 panic: sync: negative WaitGroup counter 的错误。

你有两个 Goroutine:
1 - go say("world")
2 - say("hello")main Goroutine 中
所以使用 w.Add(2),可以参考这个工作示例(The Go Playground):

package main

import (
	"fmt"
	"sync"
	"time"
)

var w sync.WaitGroup

func say(s string) {
	for i := 0; i < 2; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	w.Done()
}

func main() {
	w.Add(2)
	go say("world")
	say("hello")
	w.Wait()
}

输出结果:

world
hello
hello
world

希望对你有所帮助。

英文:

w.Done() decrements the WaitGroup counter.
So your code even sometimes panic: sync: negative WaitGroup counter.

You have two Goroutines:
1 - go say(&quot;world&quot;)
2 - say(&quot;hello&quot;) inside main Goroutine
so use w.Add(2), see this working sample (The Go Playground):

<!-- language: lang-golang -->

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

var w sync.WaitGroup

func say(s string) {
	for i := 0; i &lt; 2; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	w.Done()
}

func main() {
	w.Add(2)
	go say(&quot;world&quot;)
	say(&quot;hello&quot;)
	w.Wait()
}

output:

world
hello
hello
world

I hope this helps.

答案2

得分: 0

你只是将WaitGroup增加了1,但是从两个say的调用中调用了Done。

在你的示例中,如果将WaitGroup的初始值设为2,就可以正常工作。

w.Add(2)
英文:

You're only adding 1 to the WaitGroup, but calling Done from 2 invocations of say.

In your example, starting the WaitGroup with 2 would work

w.Add(2)

答案3

得分: 0

问题是由于对w.Done()的无条件调用而引起的。所以当你调用say("hello")时,这也会减少waitGroup的计数器。

请参考 https://play.golang.org/p/wJeAyYyjA2

    package main
    
    import (
    	"fmt"
    	"sync"
    	"time"
    )
    
    var w sync.WaitGroup
    
    func say(s string, async bool) {
    	if async {
    		defer w.Done()
    	}
    	for i := 0; i < 2; i++ {
    		time.Sleep(100 * time.Millisecond)
    		fmt.Println(s)
    	}
    }
    
    func main() {
    	w.Add(1)
    	go say("world", true)
    	say("hello", false)
    	w.Wait()
    }
英文:

Problem occurs due to unconditional call to w.Done(). So when u called say("hello") this also decremented counter for waitGroup.

Refer https://play.golang.org/p/wJeAyYyjA2

    package main
    
    import (
    	&quot;fmt&quot;
    	&quot;sync&quot;
    	&quot;time&quot;
    )
    
    var w sync.WaitGroup
    
    func say(s string, async bool) {
    	if async {
    		defer w.Done()
    	}
    	for i := 0; i &lt; 2; i++ {
    		time.Sleep(100 * time.Millisecond)
    		fmt.Println(s)
    	}
    }
    
    func main() {
    	w.Add(1)
    	go say(&quot;world&quot;, true)
    	say(&quot;hello&quot;, false)
    	w.Wait()
    }

huangapple
  • 本文由 发表于 2016年9月8日 13:24:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/39383135.html
匿名

发表评论

匿名网友

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

确定