Goroutines 通道和 "stopping short"
Goroutines channels and "stopping short"
我 reading/working 到 Go Concurrency Patterns: Pipelines and cancellation,但我无法理解 停止做空 部分。我们有以下功能:
func sq(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
func merge(cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int, 1) // enough space for the unread inputs
// Start an output goroutine for each input channel in cs. output
// copies values from c to out until c is closed, then calls wg.Done.
output := func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}
wg.Add(len(cs))
for _, c := range cs {
go output(c)
}
// Start a goroutine to close out once all the output goroutines are
// done. This must start after the wg.Add call.
go func() {
wg.Wait()
close(out)
}()
return out
}
func main() {
in := gen(2, 3)
// Distribute the sq work across two goroutines that both read from in.
c1 := sq(in)
c2 := sq(in)
// Consume the first value from output.
out := merge(c1, c2)
fmt.Println(<-out) // 4 or 9
return
// Apparently if we had not set the merge out buffer size to 1
// then we would have a hanging go routine.
}
现在,如果您注意到 merge
中的第 2
行,它表示我们用 buffer
尺寸 1 制作 chan
,因为这足够 space 用于未读输入。但是,我几乎肯定我们应该分配 buffer
大小为 2 的 chan
。根据此代码示例:
c := make(chan int, 2) // buffer size 2
c <- 1 // succeeds immediately
c <- 2 // succeeds immediately
c <- 3 // blocks until another goroutine does <-c and receives 1
因为本节暗示 buffer
尺寸 3 的 chan
不会阻塞。任何人都可以 clarify/assist 我的理解吗?
程序向通道out
发送两个值并从通道out
读取一个值。未收到其中一个值。
如果通道是无缓冲的(容量为 0),那么其中一个发送 goroutine 将阻塞直到程序退出。这是一个漏洞。
如果创建的通道容量为 1,那么两个 goroutine 都可以发送到通道并退出。发送到通道的第一个值由 main
接收。第二个值保留在通道中。
如果 main 函数没有从通道 out
接收到值,则需要一个容量为 2 的通道来防止 goroutines 无限期阻塞。
我 reading/working 到 Go Concurrency Patterns: Pipelines and cancellation,但我无法理解 停止做空 部分。我们有以下功能:
func sq(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
func merge(cs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int, 1) // enough space for the unread inputs
// Start an output goroutine for each input channel in cs. output
// copies values from c to out until c is closed, then calls wg.Done.
output := func(c <-chan int) {
for n := range c {
out <- n
}
wg.Done()
}
wg.Add(len(cs))
for _, c := range cs {
go output(c)
}
// Start a goroutine to close out once all the output goroutines are
// done. This must start after the wg.Add call.
go func() {
wg.Wait()
close(out)
}()
return out
}
func main() {
in := gen(2, 3)
// Distribute the sq work across two goroutines that both read from in.
c1 := sq(in)
c2 := sq(in)
// Consume the first value from output.
out := merge(c1, c2)
fmt.Println(<-out) // 4 or 9
return
// Apparently if we had not set the merge out buffer size to 1
// then we would have a hanging go routine.
}
现在,如果您注意到 merge
中的第 2
行,它表示我们用 buffer
尺寸 1 制作 chan
,因为这足够 space 用于未读输入。但是,我几乎肯定我们应该分配 buffer
大小为 2 的 chan
。根据此代码示例:
c := make(chan int, 2) // buffer size 2
c <- 1 // succeeds immediately
c <- 2 // succeeds immediately
c <- 3 // blocks until another goroutine does <-c and receives 1
因为本节暗示 buffer
尺寸 3 的 chan
不会阻塞。任何人都可以 clarify/assist 我的理解吗?
程序向通道out
发送两个值并从通道out
读取一个值。未收到其中一个值。
如果通道是无缓冲的(容量为 0),那么其中一个发送 goroutine 将阻塞直到程序退出。这是一个漏洞。
如果创建的通道容量为 1,那么两个 goroutine 都可以发送到通道并退出。发送到通道的第一个值由 main
接收。第二个值保留在通道中。
如果 main 函数没有从通道 out
接收到值,则需要一个容量为 2 的通道来防止 goroutines 无限期阻塞。