有两个问题
- 使用非缓冲通道: 非缓冲通道会阻塞接收者,直到通道上有可用数据,并阻塞发送者,直到接收者可用。这导致了错误。
- 在 range 之前未关闭通道: 因为你从未关闭 ch 通道,所以 range 循环永远不会结束。
你必须使用一个 缓冲通道
并在 range 之前 关闭
通道
代码
package main
import (
"fmt"
"sync"
)
func double(line int, ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
ch <- line * 2
}
func main() {
contents := []int{1, 2, 3, 4, 5}
sampleChan := make(chan int,len(contents))
var wg sync.WaitGroup
for _, line := range contents {
wg.Add(1)
go double(line, sampleChan, &wg)
}
wg.Wait()
close(sampleChan)
var sampleList []int
for s := range sampleChan {
sampleList = append(sampleList, s)
}
fmt.Println(sampleList)
}
播放链接: https://play.golang.org/p/k03vt3hd3P
编辑: 为了更好的性能表现,另一种方法是同时运行producer
和consumer
修改后的代码
package main
import (
"fmt"
"sync"
)
func doubleLines(lines []int, wg *sync.WaitGroup, sampleChan chan int) {
defer wg.Done()
defer close(sampleChan)
var w sync.WaitGroup
for _, line := range lines {
w.Add(1)
go double(&w, line, sampleChan)
}
w.Wait()
}
func double(wg *sync.WaitGroup, line int, ch chan int) {
defer wg.Done()
ch <- line * 2
}
func collectResult(wg *sync.WaitGroup, channel chan int, sampleList *[]int) {
defer wg.Done()
for s := range channel {
*sampleList = append(*sampleList, s)
}
}
func main() {
contents := []int{0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
sampleChan := make(chan int, 1)
var sampleList []int
var wg sync.WaitGroup
wg.Add(1)
go doubleLines(contents, &wg, sampleChan)
wg.Add(1)
go collectResult(&wg, sampleChan, &sampleList)
wg.Wait()
fmt.Println(sampleList)
}
play link: https://play.golang.org/p/VAe7Qll3iVM
newSample
是如何实现的? - kennytmsample
发送到通道中。 - kentwait