2016-03-18 19 views
2

Git paralelinde korelasyonları hesaplamak istiyorum. Sahip olduğum asıl sorun, tüm Go işlemlerinin tamamen aynı hesaplamayı yürütmesidir. Buradaki problemi çok basit bir örnekle yeniden ürettim. Ben edinin:Git paralelinde işleme dizileri beklenmedik sonuçlar verir

4 + 50 = 54 
4 + 50 = 54 
4 + 50 = 54 

yerine:

1 + 20 = 21 
2 + 30 = 32 
3 + 40 = 43 

ben "wg.Wait()" Ben iyi bir sonuç ama hiçbir paralellik :(elde yukarı taşırsanız Yorumlarınızı için şimdiden Teşekkür'ın! döngü halindeyken herhangi önce bitirmesi olur çünkü tüm goroutines içinde i aynı kopyasını erişiyorsunuz

package main 

    import (
     "fmt" 
     "runtime" 
     "sync" 
    ) 

    func process_array(x, y int) int { 
     r := x + y 
     return r 
    } 


    func main() { 
     a1 := []int{0, 1, 2, 3, 4} 
     a2 := []int{10, 20, 30, 40, 50} 

     runtime.GOMAXPROCS(8) 
     var wg sync.WaitGroup 

     for i := 1; i < 4 ; i++ { 
      wg.Add(1) 
      go func() { 
       defer wg.Done() 
       x :=process_array(a1[i],a2[i]) 
       fmt.Println(a1[i],"+", a2[i],"=", x) 
      }() 
      //wg.Wait() give the good result 
         //but it is not parallel processing 
         // 1 + 20 = 21 
         // 2 + 30 = 32 
         // 3 + 40 = 43 
      } 
     wg.Wait() // give a repetition of the same result : 
        // 4 + 50 = 54 
        // 4 + 50 = 54 
        // 4 + 50 = 54 

    } 
+3

SSS: https://golang.org/doc/faq#closures_and_goroutines, pratik olarak, kendi goroutines vermek istiyorum – JimB

+0

Not Daha büyük görevler (örneğin, N cpus'unuz varsa, her 1/n'yi yapmak için verin). Bir ek çok hızlı ve bir iş parçacığı başlatmak için koordinasyon ve böylece giriş yapar. – twotwotwo

cevap

3

. Gördüğünüz çıkışı rutinleri yürütmeye başlar.

Bu, i'un tüm goroutines'de, yani döngüde sahip olduğu son değerin aynı değere sahip olduğu anlamına gelir.

i'u, her birinizin bir argümanı olarak geçirerek, bunun yerine, her bir kopya başına bir kopya üzerinde çalışarak, bu sorunu çözer.

Döngüye wg.Wait() eklediğinizde beklediğiniz sonucu görmenizin sebebi, daha sonra bir sonraki başlatmaya başlamadan önce, goroutine öğesinin bitmesini beklerken senkronizasyonu başlattığınızdır. Bu, yürütmenin aslında seri olduğu anlamına geliyor, paralel değil. İşte

beklediğiniz gibi çalışır güncellenen kod verilmiştir:

package main 

import (
    "fmt" 
    "runtime" 
    "sync" 
) 

func process_array(x, y int) int { 
    r := x + y 
    return r 
} 

func main() { 
    a1 := []int{0, 1, 2, 3, 4} 
    a2 := []int{10, 20, 30, 40, 50} 

    runtime.GOMAXPROCS(8) 
    var wg sync.WaitGroup 

    for i := 1; i < 4; i++ { 
     wg.Add(1) 
     go func(i int) { 
      defer wg.Done() 
      x := process_array(a1[i], a2[i]) 
      fmt.Println(a1[i], "+", a2[i], "=", x) 
     }(i) 
     //wg.Wait() give the good result 
     //but it is not parallel processing 
     // 1 + 20 = 21 
     // 2 + 30 = 32 
     // 3 + 40 = 43 
    } 
    wg.Wait() // give a repetition of the same result : 
    // 4 + 50 = 54 
    // 4 + 50 = 54 
    // 4 + 50 = 54 

} 
+0

veya ortak 'i: = i' idom: http://play.golang.org/p/Zcof5HLrQr – JimB

+0

Evet, bu da işe yarıyor. Bu yolu daha net buluyorum. –

+0

Vay canına! etkileyici bir çözüm, basit ama bulmak zor! Teşekkürler ! – Fred

İlgili konular