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

在 Goroutine 中延迟调用sync.WaitGroup.Wait():为什么这会起作用?

在 Goroutine 中延迟调用sync.WaitGroup.Wait():为什么这会起作用?

Go
慕丝7291255 2023-08-07 10:46:15
我试图理解负载测试工具/库的源代码中的Attack()函数(https://github.com/tsenart/vegeta/blob/44a49c878dd6f28f04b9b5ce5751490b0dce1e18/lib/attack.go#L253-L312vegeta ) 。我创建了一个简化的示例:package mainimport (    "fmt"    "sync"    "time")func main() {    var wg sync.WaitGroup    for i := 0; i < 10; i++ {        wg.Add(1)        go attack(&wg)    }    // wg.Wait()    go func() {        defer wg.Wait()    }()}func attack(wg *sync.WaitGroup) {    defer wg.Done()    time.Sleep(1 * time.Second)    fmt.Println("foobar")}我注意到这个函数立即返回而没有打印foobar10 次。仅当wg.Wait()我看到该行中的注释foobar在 1 秒后打印了 10 次时。这对我来说很有意义,因为函数在调用main()之前返回。wg.Wait()该attack()方法读取的位置func (a *Attacker) attack(tr Targeter, name string, workers *sync.WaitGroup, ticks <-chan struct{}, results chan<- *Result) {    defer workers.Done()    for range ticks {        results <- a.hit(tr, name)    }}我不明白为什么该Attack()函数在不调用的情况下不会立即返回attack(),因为它wg.Wait()位于 Goroutine 内部?
查看完整描述

1 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

vegeta 也会Attack立即返回,但通道中填充有仍在运行的 goroutine。一旦这些完成,通道就会关闭(defer close(results)),从而启用必须检测完成的代码result。


例子;


package main


import (

    "fmt"

    "sync"

    "time"

)


func main() {

    results := attacks()


    fmt.Println("attacks returned")


    for result := range results {

        fmt.Println(result)

    }

}


func attacks() chan string {

    // A channel to hold the results

    c := make(chan string)


    // Fire 10 routines populating the channel

    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {

        wg.Add(1)

        go func() {

            attack(c)

            wg.Done()

        }()

    }


    // Close channel once routines are finished

    go func() {

        wg.Wait()

        close(c)

    }()


    //

    return c

}


func attack(c chan<- string) {

    time.Sleep(1 * time.Second)

    c <- "foobar"

}


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 74 浏览
慕课专栏
更多

添加回答

举报

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