我正在尝试按照 Go Concurrency 书实现桥接模式func bridge_impl() { done := make(chan interface{}) defer close(done) var wg sync.WaitGroup bridge := func( done <-chan interface{}, chanStream <-chan <-chan interface{}, ) <-chan interface{} { valStream := make(chan interface{}) go func() { wg.Add(1) defer close(valStream) for { var stream <-chan interface{} select { case maybeStream, ok := <-chanStream: fmt.Println("works") if ok == false { return } stream = maybeStream case <-done: return } for val := range stream { select { case valStream <- val: case <-done: } } } }() return valStream } genVals := func() <-chan <-chan interface{} { chanStream := make(chan (<-chan interface{})) go func() { wg.Add(1) defer close(chanStream) for i := 0; i < 10; i++ { stream := make(chan interface{}) stream <- i close(stream) chanStream <- stream } }() return chanStream } for v := range bridge(done, genVals()) { fmt.Printf("%v ", v) } wg.Wait()}但是我一开始收到一个死锁错误all goroutines are asleep - deadlock!,我想我应该添加一个等待组,即使它没有在书中的例子中实现,但我最终还是遇到了同样的错误
2 回答
DIEA
TA贡献1820条经验 获得超2个赞
据我了解,您根本不需要 WaitGroup,您只需要重新排序genVals函数循环中的语句:
for i := 0; i < 10; i++ {
stream := make(chan interface{})
chanStream <- stream
stream <- i
close(stream)
}
https://go.dev/play/p/7D9OzrsvZyi
茅侃侃
TA贡献1842条经验 获得超21个赞
有两个主要问题。
第一期:
for i := 0; i < 10; i++ {
stream := make(chan interface{})
stream <- i
close(stream)
chanStream <- stream
}
创建后写入无缓冲通道,没有 goroutine 读取。使用缓冲通道或其他 goroutine。
stream := make(chan interface{}, 1) // buffer size 1 to not block `stream <- i`
第二期:不
使用。 您可以在这两种情况下使用。wg.Add(1)wg.Done()
defer
wg.Add(1)
defer wg.Done()
- 2 回答
- 0 关注
- 135 浏览
添加回答
举报
0/150
提交
取消