我有以下代码:
package main
import (
"errors"
"fmt"
"sync"
"time"
er "github.com/pkg/errors"
)
func main() {
var wg sync.WaitGroup
errorsChan := make(chan error) // remove the length and see the error happens!
wg.Add(1)
go func() {
defer wg.Done()
wg.Add(1)
go func() {
defer wg.Done()
say(5)
errorsChan <- er.Wrap(errors.New("first one"), "first test")
}()
wg.Add(1)
go func() {
defer wg.Done()
say(1)
errorsChan <- er.Wrap(errors.New("something"), "another test")
}()
}()
go func() {
wg.Wait()
close(errorsChan)
}()
for item := range errorsChan {
fmt.Println(item)
}
// time.Sleep(10*time.Second)
fmt.Print("HELLO\n")
}
func say(i time.Duration) {
time.Sleep(i * time.Second)
}
我想在错误消息之前先打印
HELLO
。
现在
HELLO
正在等待上面的错误消息,然后被打印出来。
如果我删除顶层wg.Add(1)
然后我收到错误panic: send on closed channel
我应该做出什么改变?
阅读代码后,我找到了解决方案。
i 应该将
wg.Wait()
和 close(errorsChan)
代码放在顶级 go 例程中。因为这是需要 errorsChan
的地方,所以打印 HELLO
可以在主要的 go 程序中进行。
所以正确答案如下:
package main
import (
"errors"
"fmt"
"sync"
"time"
er "github.com/pkg/errors"
)
func main() {
var wg sync.WaitGroup
errorsChan := make(chan error) // remove the length and see the error happens!
wg.Add(1)
go func() {
defer wg.Done()
wg.Add(1)
go func() {
defer wg.Done()
say(5)
errorsChan <- er.Wrap(errors.New("first one"), "first test")
}()
wg.Add(1)
go func() {
defer wg.Done()
say(1)
errorsChan <- er.Wrap(errors.New("something"), "another test")
}()
go func() {
wg.Wait()
close(errorsChan)
}()
for item := range errorsChan {
fmt.Println(item)
}
}()
// time.Sleep(10*time.Second)
fmt.Print("HELLO\n")
}
func say(i time.Duration) {
time.Sleep(i * time.Second)
}