dongzhi4073 2016-11-16 21:30
浏览 49
已采纳

保存并行goroutine的结果

I am trying to parallelize an operation in golang and save the results in a manner that I can iterate over to sum up afterwords.

I have managed to set up the parameters so that no deadlock occurs, and I have confirmed that the operations are working and being saved correctly within the function. When I iterate over the Slice of my struct and try and sum up the results of the operation, they all remain 0. I have tried passing by reference, with pointers, and with channels (causes deadlock).

I have only found this example for help: https://golang.org/doc/effective_go.html#parallel. But this seems outdated now, as Vector as been deprecated? I also have not found any references to the way this function (in the example) was constructed (with the func (u Vector) before the name). I tried replacing this with a Slice but got compile time errors.

Any help would be very appreciated. Here is the key parts of my code:

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)
}

Here is the code running on the go playground https://play.golang.org/p/X5IYaG36U-

  • 写回答

1条回答 默认 最新

  • dongshan4878 2016-11-16 21:39
    关注

    As long as the []Job slice is only modified by one goroutine at a time, there's no reason you can't modify the job in place.

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

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

    You should also use a WaitGroup, rather than rely on counting tokens in a channel yourself.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题