问题发生原因
由于超时退出函数,导致chanel的读监听动作也随之退出,从而导致协程内channel的写操作被阻塞导致协程永不会退出。
核心代码如下:
package main
import (
"context"
"github.com/siddontang/go/log"
"sync"
"time"
)
func f1() {
var (
wg sync.WaitGroup
c = make(chan int)
ctx = context.Background()
cancel context.CancelFunc
)
ctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
defer cancel()
for i := 0; i < 10; i++ {
wg.Add(1)
routinePool.AddTask(func() {
defer wg.Done()
f2(ctx, &wg, c)
})
}
go func() {
wg.Wait()
close(c)
}()
for {
select {
case res, ok := <-c:
if !ok {
return
}
handleResult(res)
case <-ctx.Done():
log.Error("Timeout")
return
}
}
}
func f2(ctx context.Context, wg *sync.WaitGroup, c chan int) {
defer func() {
wg.Done()
}()
doSomething()
select {
case <-ctx.Done():