相关疑难解决方法(0)

我可以同时写入不同的切片元素

我有一个包含要完成的工作的切片,以及在完成所有操作时将包含结果的切片.以下是我的一般过程的草图:

var results = make([]Result, len(jobs))
wg := sync.WaitGroup{}
for i, job := range jobs {
    wg.Add(1)
    go func(i int, j job) {
        defer wg.Done()
        var r Result = doWork(j)
        results[i] = r
    }(i, job)
}
wg.Wait()
// Use results
Run Code Online (Sandbox Code Playgroud)

它似乎工作,但我没有彻底测试,我不确定它是否安全.一般来说,让多个goroutine写入任何内容都不会让我感觉良好,但在这种情况下,每个goroutine都限制在切片中自己的索引,这是预先分配的.

我想替代方案是通过渠道收集结果,但由于结果顺序很重要,这似乎相当简单.以这种方式写入切片元素是否安全?

concurrency go slice goroutine

18
推荐指数
2
解决办法
1832
查看次数

将多个 go 例程的响应获取到一个数组中

我需要从多个 go 例程中获取响应并将它们放入一个数组中。我知道可以为此使用通道,但是我不确定如何确保所有 go 例程都完成了对结果的处理。因此我使用了一个等待组。

代码

func main() {
  log.Info("Collecting ints")
  var results []int32
  for _, broker := range e.BrokersByBrokerID {
      wg.Add(1)
      go getInt32(&wg)
  }
  wg.Wait()
  log.info("Collected")
}

func getInt32(wg *sync.WaitGroup) (int32, error) {
  defer wg.Done()

  // Just to show that this method may just return an error and no int32
  err := broker.Open(config)
  if err != nil && err != sarama.ErrAlreadyConnected {
    return 0, fmt.Errorf("Cannot connect to broker '%v': %s", broker.ID(), err)
  }
  defer broker.Close()

  return 1003, nil
} …
Run Code Online (Sandbox Code Playgroud)

concurrency go goroutine

2
推荐指数
2
解决办法
2134
查看次数

重构代码以按惯用方式使用单个通道

我有以下代码:

package main

import (
    "fmt"
    "time"
)

type Response struct {
    Data   string
    Status int
}

func main() {
    var rc [10]chan Response
    for i := 0; i < 10; i++ {
        rc[i] = make(chan Response)
    }
    var responses []Response

    for i := 0; i < 10; i++ {
        go func(c chan<- Response, n int) {
            c <- GetData(n)
            close(c)
        }(rc[i], i)
    }

    for _, resp := range rc {
        responses = append(responses, <-resp)
    }

    for _, item := …
Run Code Online (Sandbox Code Playgroud)

arrays concurrency channel go slice

1
推荐指数
1
解决办法
87
查看次数

Go中令人难以置信的并行任务的惯用解决方案是什么?

我目前正在盯着以下代码的增强版本:

func embarrassing(data []string) []string {
  resultChan := make(chan string)
  var waitGroup sync.WaitGroup
  for _, item := range data {
    waitGroup.Add(1)
    go func(item string) {
      defer waitGroup.Done()
      resultChan <- doWork(item)
    }(item)
  }

  go func() {
    waitGroup.Wait()
    close(resultChan)
  }()

  var results []string
  for result := range resultChan {
    results = append(results, result)
  }
  return results
}
Run Code Online (Sandbox Code Playgroud)

这只是在想我的想法.所有这一切都可以用其他语言表达为

results = parallelMap(data, doWork)
Run Code Online (Sandbox Code Playgroud)

即使在Go中不能轻易做到这一点,是不是还有比上面更好的方法呢?

concurrency channel go goroutine

-2
推荐指数
1
解决办法
357
查看次数

标签 统计

concurrency ×4

go ×4

goroutine ×3

channel ×2

slice ×2

arrays ×1