Golang:为什么增加缓冲通道的大小会消除我的 goroutines 的输出?
Golang: Why does increasing the size of a buffered channel eliminate output from my goroutines?
我试图理解为什么使通道的缓冲区大小发生较大变化会导致我的代码意外 运行。如果缓冲区小于我的输入(100 个整数),则输出符合预期,即 7 个 goroutine 每个读取输入的一个子集并在打印它的另一个通道上发送输出。如果缓冲区与输入大小相同或更大,则我没有输出也没有错误。我是否在错误的时间关闭了频道?我对缓冲区的工作方式有错误的期望吗?或者,别的什么?
package main
import (
"fmt"
"sync"
)
var wg1, wg2 sync.WaitGroup
func main() {
share := make(chan int, 10)
out := make(chan string)
go printChan(out)
for j:= 1; j<=7; j++ {
go readInt(share, out, j)
}
for i:=1; i<=100; i++ {
share <- i
}
close(share)
wg1.Wait()
close(out)
wg2.Wait()
}
func readInt(in chan int, out chan string, id int) {
wg1.Add(1)
for n := range in {
out <- fmt.Sprintf("goroutine:%d was sent %d", id, n)
}
wg1.Done()
}
func printChan(out chan string){
wg2.Add(1)
for l := range out {
fmt.Println(l)
}
wg2.Done()
}
给运行这个:
小缓冲区,预期输出。 http://play.golang.org/p/4r7rTGypPO
大缓冲区,没有输出。 http://play.golang.org/p/S-BDsw7Ctu
这与缓冲区的大小没有直接关系。添加缓冲区会在您调用 waitGroup.Add(1)
的地方暴露错误
你必须添加到 WaitGroup
before 你派遣 goroutine,否则你最终可能会调用 Wait()
before waitGroup.Add(1)
执行。
http://play.golang.org/p/YaDhc6n8_B
它在第一个而不是第二个中起作用的原因是因为同步发送确保 gouroutines 至少执行了那么远。在第二个示例中,for 循环填满通道,关闭它并在其他任何事情发生之前调用 Wait。
我试图理解为什么使通道的缓冲区大小发生较大变化会导致我的代码意外 运行。如果缓冲区小于我的输入(100 个整数),则输出符合预期,即 7 个 goroutine 每个读取输入的一个子集并在打印它的另一个通道上发送输出。如果缓冲区与输入大小相同或更大,则我没有输出也没有错误。我是否在错误的时间关闭了频道?我对缓冲区的工作方式有错误的期望吗?或者,别的什么?
package main
import (
"fmt"
"sync"
)
var wg1, wg2 sync.WaitGroup
func main() {
share := make(chan int, 10)
out := make(chan string)
go printChan(out)
for j:= 1; j<=7; j++ {
go readInt(share, out, j)
}
for i:=1; i<=100; i++ {
share <- i
}
close(share)
wg1.Wait()
close(out)
wg2.Wait()
}
func readInt(in chan int, out chan string, id int) {
wg1.Add(1)
for n := range in {
out <- fmt.Sprintf("goroutine:%d was sent %d", id, n)
}
wg1.Done()
}
func printChan(out chan string){
wg2.Add(1)
for l := range out {
fmt.Println(l)
}
wg2.Done()
}
给运行这个: 小缓冲区,预期输出。 http://play.golang.org/p/4r7rTGypPO 大缓冲区,没有输出。 http://play.golang.org/p/S-BDsw7Ctu
这与缓冲区的大小没有直接关系。添加缓冲区会在您调用 waitGroup.Add(1)
你必须添加到 WaitGroup
before 你派遣 goroutine,否则你最终可能会调用 Wait()
before waitGroup.Add(1)
执行。
http://play.golang.org/p/YaDhc6n8_B
它在第一个而不是第二个中起作用的原因是因为同步发送确保 gouroutines 至少执行了那么远。在第二个示例中,for 循环填满通道,关闭它并在其他任何事情发生之前调用 Wait。