2009-11-13 9 views
8

Alle Beispiele, die ich bisher gesehen habe Blockierung beinhalten das Ergebnis (über den <-chan Operator) zu erhalten.Wie finde ich heraus, ob eine Goroutine durchgeführt wurde, ohne zu blockieren?

Mein aktueller Ansatz beinhaltet einen Zeiger auf eine Struktur übergeben:

type goresult struct { 
    result resultType; 
    finished bool; 
} 

welche die goroutine nach Abschluss schreibt. Dann ist es einfach, finished zu überprüfen, wann immer es bequem ist. Hast du bessere Alternativen?

Was ich bin mit dem Ziel wirklich für ein Qt-Stil Signal-Slot-System. Ich habe das Gefühl, die Lösung fast trivial aussehen (chan s haben viele unerforschtes Potential), aber ich bin noch nicht vertraut genug mit der Sprache, es herauszufinden.

Antwort

13

Sie können das „Komma, ok“ verwenden Muster (die Seite auf „effective go“ sehen):

foo  := <- ch; // This blocks. 
foo, ok := <- ch; // This returns immediately. 
+1

das ist nicht mehr gültig. – rog

+1

Sie schreiben: wählen { Fall foo: = <-ch: default: } – rog

4

Select statements können Sie mehrere Kanäle auf einmal, wobei eine zufällige Verzweigung überprüfen (von denen, in denen die Kommunikation wartet):

func main() { 
    for { 
    select { 
     case w := <- workchan: 
      go do_work(w) 
     case <- signalchan: 
      return 
     // default works here if no communication is available 
     default: 
      // do idle work 
    } 
    } 
} 

Für alle Sende- und Ausdrücke in der „select“ erhalten Anweisung, die Kanal Ausdrücke ausgewertet werden, zusammen mit irgendwelchen Ausdrücke, die auf der rechten Seite der Ausdrücke senden, in top-to-bottom Reihenfolge erscheinen. Wenn eine der daraus resultierenden Operationen können fortzufahren, wird eine ausgewählt und die entsprechende Kommunikation und Aussagen ausgewertet werden. Sonst wenn es einen Standardfall gibt, der ausführt; wenn nicht, blockiert die Anweisung , bis eine der Kommunikationen abgeschlossen werden kann.

+0

@Jurily: Bist du dir da sicher? Es sollte korrekt sein, würde aber ohne den Platz nach '<-' besser aussehen. – u0b34a0f6ae

+0

+1; Verwenden Sie immer gofmt, wenn Sie den Go-Code veröffentlichen. – rog

3

Sie können an dem Kanalpuffer zu sehen, auch spähen, ob es etwas enthält, die durch len mit :

if len(channel) > 0 { 
    // has data to receive 
} 

Dies wird den Kanalpuffer nicht berühren, anders als die, wenn foo, gotValue := <- chgotValue == true Wert entfernt.