Goroutine并行执行确认

标签 go goroutine channels

我是 goroutines、channels 之类的新手,如果这看起来微不足道,我深表歉意。

我写了下面的代码:

for _, h := range hosts {

      go func() {
        httpClient := cleanhttp.DefaultPooledClient()

        // format the URL with the passed host and por
        url := fmt.Sprintf("https://%s:%v", h.Name, h.Port)
        // create a vault client
        client, err := api.NewClient(&api.Config{Address: url, HttpClient: httpClient})
        if err != nil {
          panic(err)
        }
        // get the current status
        status := v.VaultStatus(client)

        // send the status to a channel
        s <- strconv.FormatBool(status.Ready)

      }()

      // assign the value of channel to a var
      cs := <-s

      // print it
      fmt.Printf("Host: %s Status:  %s\n", h.Name, cs)

    }
  }, 

这个想法很简单,它需要一个主机列表,然后使用 Golang Vault API 去确定当前状态。我很高兴它有效。

我想做的是确保这些操作并行进行。当我运行以下代码时,我得到如下结果:

host: Host1: status: true
host: Host2: status: false
host: Host3: status: true
host: Host4: status: true

这里的问题是这些主机总是以相同的顺序返回。我认为 goroutines 根本不是并行执行的,因为它们似乎一个接一个地运行,然后每次都以相同的顺序打印。

代码是否按照我认为应该的方式运行?我如何知道这个 goroutine 是并行运行的?

最佳答案

您一次只运行一个 goroutine,因为主 goroutine 在继续循环的下一次迭代之前在 channel 上等待。相反,您应该在所有 goroutine 启动后等待 for 循环外的 channel 上的结果。顺便说一句,您还需要在 channel 上发送一些标识主机的内容。

顺便说一下,你的 goroutine 函数有一个潜在的问题。您正在使用变量 h,每次循环都会由主 goroutine 更改,因此您真的不知道在其他 goroutine 中得到了什么(假设您小心我上面提到的问题,以便 goroutines 并行运行)。您不应直接引用该变量,而应将其作为参数传递给 goroutine 函数(或者您可以在 for 循环内创建一个不同的变量并为其分配 h 的值并在函数)。

尝试这样做:

var wg sync.WaitGroup
for _, h := range hosts {
    h := h // create local copy of loop var
    wg.Add(1)
    go func() {
        defer wg.Done()
        httpClient := cleanhttp.DefaultPooledClient()

        // format the URL with the passed host and por
        url := fmt.Sprintf("https://%s:%v", h.Name, h.Port)
        // create a vault client
        client, err := api.NewClient(&api.Config{Address: url, HttpClient: httpClient})
        if err != nil {
            panic(err)
        }
        // get the current status
        status := v.VaultStatus(client)

        // print it
        fmt.Printf("Host: %s Status:  %v\n", h.Name, status.Ready)

    }()
}
wg.Wait()

关于Goroutine并行执行确认,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42753067/

相关文章:

for-loop - "Select"goroutine 内的 for 循环语句

python - 信号和 django channel 聊天室

go - 非阻塞 readline 挂起时泄漏 goroutine

go - 长时间运行复制到 bytes.Buffer

go - decodeRuneInternal 和 decodeRuneInStringInternal 有什么区别

go - 如何在 Golang 中使用 JWT 获得响应

loops - 将 goroutine 的结果传递给循环内的变量

javascript - 通过 Django Channels 和 Websockets 向客户端推送实时更新

performance - 如何有效利用 channel

go - go.mod 文件放在哪里