2016-11-16 138 views
0

我想在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) 
} 

下面是在旅途中操場上運行的代碼https://play.golang.org/p/X5IYaG36U-

回答

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,而不是依靠一個通道計數自己的令牌。

+0

所以問題在於直接修改job元素而不是jobs [i]。經典的愚蠢錯誤。謝謝! – mtonsmann

+0

@mtonsmann:注意使用'[] * Job'也可以工作,甚至可能更好,這取決於你實際的'Job'類型是什麼。 – JimB