我正在尝试并行化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-
上运行的代码答案 0 :(得分:2)
只要[]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,而不是依靠自己计算频道中的令牌。