【问题标题】:Concurrency in GoGo 中的并发
【发布时间】:2019-05-09 15:07:41
【问题描述】:

如何在 Go 中实现聚合模式,我必须同时发送一堆 http 请求,每个 go 例程将调用端点并在通道上发送响应状态。现在在主调用函数上,我将遍历通道并显示所有响应。

问题是如何解锁频道? - 我无法从 go 例程中关闭通道,因为它将在完成工作之前关闭

主包

import (
    "fmt"
    "net/http"
    "sync"
    "time"

    "golang.org/x/net/context"
)

func main() {

    var wg sync.WaitGroup
    wg.Add(10)
    c := make(chan string, 100)
    ctx := context.Background()

    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)

    defer cancel()
    for i := 1; i <= 10; i++ {
        go SendHttpRequest(ctx, c, &wg)
    }

    for v := range c {
        fmt.Println(v)
    }

    wg.Wait()

}

func SendHttpRequest(ctx context.Context, c chan string, wg *sync.WaitGroup) {

    //defer wg.Done()
    client := http.Client{}
    req, err := http.NewRequest("POST", "https://jsonplaceholder.typicode.com/posts/1", nil)
    if err != nil {
        panic(err)
    }
    req.WithContext(ctx)

    res, _ := client.Do(req)

    select {
    case <-time.After(1 * time.Microsecond):
        c <- res.Status
    case <-ctx.Done():
        c <- "599 ToLong"
    }
    if res != nil {
        defer res.Body.Close()
    }
    //close(c)
    defer wg.Done()
}

【问题讨论】:

  • 随机注释:将“golang.org/x/net/context”替换为“context”。我认为您应该从 1.8 开始使用“上下文”。

标签: go


【解决方案1】:

使用WaitGroup

go func(){
  wg.Wait()
  close(c)
}()

for v := range c {
  fmt.Println(v)
}

// Don't bother with wg.Wait() here

【讨论】:

  • 谢谢。它运作良好。我不认为我们可以在 goroutine 中关闭它。
  • 可以,因为代码是通过WaitGroup同步的。
猜你喜欢
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
相关资源
最近更新 更多