【问题标题】:Saving results from a parallelized goroutine保存并行 goroutine 的结果
【发布时间】:2016-11-16 21:30:25
【问题描述】:

我正在尝试在 golang 中并行化一个操作,并以一种我可以迭代以总结后记的方式保存结果。

我已经设法设置了参数,这样就不会发生死锁,并且我已经确认操作正在工作并且在函数中正确保存。当我遍历结构的 Slice 并尝试总结操作结果时,它们都保持为 0。我尝试通过引用、指针和通道传递(导致死锁)。

我只找到了这个例子来寻求帮助:https://golang.org/doc/effective_go.html#parallel。但这现在似乎已经过时了,因为 Vector 已被弃用?我也没有找到任何关于这个函数(在示例中)的构造方式的引用(在名称之前使用 func (u Vector))。我尝试用 Slice 替换它,但出现编译时错误。

任何帮助将不胜感激。这是我的代码的关键部分:

type job struct {
  a int
  b int
  result *big.Int
}

func choose(jobs []Job, c chan int) {
  temp := new(big.Int)
  for _,job := range jobs {
    job.result = //perform operation on job.a and job.b
    //fmt.Println(job.result)
  }
  c <- 1
}

func main() {
  num := 100 //can be very large (why we need big.Int)
  n := num
  k := 0
  const numCPU = 6 //runtime.NumCPU
  count := new(big.Int)

  // create a 2d slice of jobs, one for each core
  jobs := make([][]Job, numCPU)


  for (float64(k) <= math.Ceil(float64(num / 2))) {
    // add one job to each core, alternating so that
    // job set is similar in difficulty
    for i := 0; i < numCPU; i++ {
      if !(float64(k) <= math.Ceil(float64(num / 2))) {
        break
      }
      jobs[i] = append(jobs[i], Job{n, k, new(big.Int)})
      n -= 1
      k += 1
    }
  }

  c := make(chan int, numCPU)
  for i := 0; i < numCPU; i++ {
    go choose(jobs[i], c)
  }

  // drain the channel
  for i := 0; i < numCPU; i++ {
   <-c
   }
  // computations are done

 for i := range jobs {
    for _,job := range jobs[i] {
      //fmt.Println(job.result)
      count.Add(count, job.result)
    }
  }



  fmt.Println(count)
}

这是在 go playground https://play.golang.org/p/X5IYaG36U- 上运行的代码

【问题讨论】:

    标签: go concurrency parallel-processing


    【解决方案1】:

    只要 []Job 切片一次只被一个 goroutine 修改,就没有理由不能就地修改作业。

    for i, job := range jobs {
        jobs[i].result = temp.Binomial(int64(job.a), int64(job.b))
    }
    

    https://play.golang.org/p/CcEGsa1fLh

    您还应该使用 WaitGroup,而不是依靠自己计算通道中的令牌。

    【讨论】:

    • 所以问题在于直接修改job元素而不是jobs[i]。经典的愚蠢错误。谢谢!
    • @mtonsmann:请注意,使用 []*Job 也可以,甚至可能更可取,具体取决于您的实际 Job 类型。
    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 2018-04-05
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多