Cho*_*pic 3 concurrency channel go goroutine
我正在尝试Golang中的频道概念。我写了下面的程序操场来实现使用通道的计数器。但是,尽管我正在goroutine主体中进行一些打印,但是我没有得到任何输出。
func main() {
wg := sync.WaitGroup{}
ch := make(chan int)
count := func(ch chan int) {
var last int
last = <-ch
last = last + 1
fmt.Println(last)
ch <- last
wg.Done()
}
wg.Add(10)
for i := 1; i <= 10; i++ {
go count(ch)
}
}
Run Code Online (Sandbox Code Playgroud)
我希望至少有一些输出,但是我什么也得不到。
When the main() function (the main goroutine) ends, your program ends as well (it doesn't wait for other non-main goroutines to finish). You must add a wg.Wait() call to the end. See No output from goroutine in Go.
Once you do this, you'll hit a deadlock. This is because all goroutines start with attempting to receive a value from the channel, and only then would they send something.
So you should first send something on the channel to let at least one of the goroutines to proceed.
Once you do that, you'll see numbers printed 10 times, and again deadlock. This is because when the last goroutine tries to send its incremented number, there will be no one to receive that. An easy way to fix that is to give a buffer to the channel.
Final, working example:
wg := sync.WaitGroup{}
ch := make(chan int, 2)
count := func(ch chan int) {
var last int
last = <-ch
last = last + 1
fmt.Println(last)
ch <- last
wg.Done()
}
wg.Add(10)
for i := 1; i <= 10; i++ {
go count(ch)
}
go func() {
ch <- 0
}()
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
Outputs (try it on the Go Playground):
1
2
3
4
5
6
7
8
9
10
Run Code Online (Sandbox Code Playgroud)
Also note that since we made the channel buffered, it's not necessary to use another goroutine to send an initial value, we can do that in the main goroutine:
ch <- 0
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
This will output the same. Try it on the Go Playground.