为了账号安全,请及时绑定邮箱和手机立即绑定

具有并发限制但测试失败的等待组

具有并发限制但测试失败的等待组

Go
湖上湖 2022-06-27 10:58:03
我之前用过 goroutine 的 sync.WaitGroup,但是我想控制 goroutine 的并发,所以我用并发限制编写我的等待组,例如:package wglimitimport (    "sync")// WaitGroupLimit ...type WaitGroupLimit struct {    ch chan int    wg *sync.WaitGroup}// New ...func New(size int) *WaitGroupLimit {    if size <= 0 {        size = 1     }    return &WaitGroupLimit{        ch: make(chan int, size),  // buffer chan to limit concurrency        wg: &sync.WaitGroup{},    }}// Add ...func (wgl *WaitGroupLimit) Add(delta int) {    for i := 0; i < delta; i++ {        wgl.ch <- 1        wgl.wg.Add(1)    }}// Done ...func (wgl *WaitGroupLimit) Done() {    wgl.wg.Done()    <-wgl.ch}// Wait ...func (wgl *WaitGroupLimit) Wait() {    close(wgl.ch)    wgl.wg.Wait()}然后我用它来控制 goroutine 并发,例如:jobs := ["1", "2", "3", "4"] // some jobs// wg := sync.WaitGroup{} // have no concurrency limitwg := wglimit.New(2) // limit 2 goroutinefor _, job := range jobs {    wg.Add(1)    go func(job string) {        // job worker        defer wg.Done()    }(job)}wg.Wait()运行时看起来像工作。但测试失败:package wglimitimport (    "runtime"    "testing"    "time")func TestGoLimit(t *testing.T) {    var limit int = 5    wglimit := New(limit)    for i := 0; i < 10000; i++ {        wglimit.Add(1)        go func() {            defer wglimit.Done()            time.Sleep(time.Millisecond)            if runtime.NumGoroutine() > limit+2 {                println(runtime.NumGoroutine())  // will print 9 , cocurrent limit fail ?                t.Errorf("FAIL")            }        }()    }    wglimit.Wait()}测试时,goroutine 数量大于我的限制,似乎并流限制失败。我的 WaitGroupLimit 代码有什么问题,为什么?
查看完整描述

1 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

我的 WaitGroupLimit 代码 [...] 有什么问题吗?

不。

问题是runtime.NumGoroutine()没有做你认为它做的事情。它计算所有goroutine,即不仅是您启动的 goroutine,还包括运行时使用的 goroutine,例如并发垃圾收集。因此,NumGoroutine 高于您的限制。

你的代码很好,你的测试不是。不要试图在测试和测试你的代码真正做的事情时变得聪明:它会一直阻塞,Add直到有限的资源可用。测试它而不是 goroutine 计数,它只是测试中所需行为的(坏)代理。


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信