szt-sketch opened a new issue #961:
URL: https://github.com/apache/servicecomb-service-center/issues/961


   **Describe the bug**
   gopool 实现不能复用协程,  gopool 包下的goroutines.go如下代码实现导致问题:
   ``` go
   func (g *Pool) Do(f func(context.Context)) *Pool {
        defer log.Recover()
        select {
        case g.pending <- f: // block if workers are busy
        case g.workers <- struct{}{}:
                g.wg.Add(1)
                go g.loop(f)
        }
        return g
   }
   ```
   select 多个分支条件满足时,是公平调度的,所以pending 的case语句不一定先执行,当前实现会面临50%的新创建协程。
   
   实测协程复用率偏低。
   
   提供一个参考写法:
   ```
   func (g *Pool) Do(f func(context.Context)) *Pool {
        select {
        case g.pending <- f: // block if workers are busy
                fmt.Printf("eureka!")
        default:
                select {
                case g.pending <- f: // block if workers are busy
                case g.workers <- struct{}{}:
                        g.wg.Add(1)
                        go g.loop(f)
                }
        }
        return g
   }
   ```
   
   
   
   **To Reproduce**
   复现demo:
   ```
   func main() {
        var ids sync.Map
        for i := 0; i < 100; i++ {
                Go(func(context context.Context) {
                        id := Goid(); // 获取携程唯一标识id, 
                        ids.Store(id, struct {}{}) //用于统计携程创建梳理
                        fmt.Println(id, " msg: ", i)
                })
                time.Sleep(10 * time.Millisecond)
        }
   
        defaultGo.wg.Wait()
        size := 0
        ids.Range(func(_, _ interface{}) bool {
                size +=1
                return true
        })
        fmt.Println("len: ", size)
   }
   ```
   
   
   **Expected behavior**
   协程能复用,不创建新协程
   
   **Platform And Runtime (please complete the following information):**
   环境无差别,稳定复现
   
   **Additional context**
   无
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to