2017-04-23 1 views
1

Ich versuche eine Schleife von goroutines zu machen, die einen Kanal nehmen, der Zeichenfolgen empfängt, und jedes Mal, wenn es empfangen wird, sollte es den Wert an eine andere Zeichenfolge anhängen. Nur am Ende aller goroutines (die goroutine count sollte die Länge der list übergeben), sollte der Code weitermachen.goroutine, die einen Kanalempfänger nimmt und String an Kanal sendet

Mein Beispiel unten scheint die Werte aus dem strReceiver-Kanal nicht an str anzufügen, weil str nie geändert wird.

Wer weiß, was los ist?

func appendToStr(str string, list []string, origin *url.URL) { 
    var currProc int32 = 0; 
    var maxProc int32 = int32(len(list)) 

    var strReceiver := make(chan string, len(list)) 
    for _, item := range list { 
     go func() { 
      doAsyncAndIncrement(item, strReceiver, &currProc) 
      str += <-strReceiver 
     }() 
    } 

    for { 
     if atomic.LoadInt32(&currProc) <= maxProc { 
      break; 
     } 
    } 

    // continue on using 'str' which now contains the append values from the 'strReceiver' channel 
} 

func doAsyncAndIncrement(item string, receiver chan<- string, count *int32) { 
    defer atomic.AddInt32(count, 1) 

    var val string 
    // do something with 'item' and set 'val'... 

    receiver <- val 
} 
+1

Sorry, das war ein Tippfehler meinerseits. Die Async-Funktion sollte diesen Empfänger tatsächlich aufnehmen. Ich habe meinen Code aktualisiert. – Lansana

+0

'atomic.LoadInt32 (& currProc) <= maxProc 'diese Bedingung sollte nicht negiert werden? currProc wird bei der ersten Iteration durchbrechen, noch bevor die erstellten Gauner die Chance zum Laufen bekommen – nvartolomei

Antwort

1

Ein Problem mit Ihrem Code ist, dass die Schließung um Ihre Routine Routineaufruf zu groß ist.

for _, item := range list { 
    go func() { 
     doAsyncAndIncrement(item, strReceiver, &currProc) 
     str += <-strReceiver 
    }() 
} 

item ist die for-Schleife scoped, nicht die anonyme Funktion in Ihrem goroutine, also, während Sie N goroutines abzufeuern, Ihre item Variable mittlerweile in einer for-Schleife wird aktualisiert. Um dieses Problem zu beheben, übergeben Sie die Variable explizit an Ihre Goroutine, um zu vermeiden, eine Schließung zu verwenden:

for _, item := range list { 
    go func(item string) { 
     doAsyncAndIncrement(item, strReceiver, &currProc) 
     str += <-strReceiver 
    }(item) 
} 
Verwandte Themen