Lesen Was ich[Go]: Eine Datei line-by-line mit Concurrency
In GetLine
tun möchte, versuche ich eine Datei Zeile-für-Zeile zu analysieren bufio.Scanner
und ein naiver Versuch unter Verwendung von Nebenläufigkeit. Nach dem Abrufen des Textes in jeder Zeile, ich sende es über einen Kanal von string
an den Aufrufer (main
Funktion). Zusammen mit dem Wert sende ich auch Fehler und Abschlussflag (über done
Kanal). Daher sollte es möglich sein, eine neue Zeile zu holen, die in einer separaten Routine verarbeitet wird, während die aktuelle Zeile verarbeitet wird.
Was ich eigentlich getan haben
var READCOMPLETE = errors.New("Completed Reading")
func main() {
filename := flag.String("filename", "", "The file to parse")
flag.Parse()
if *filename == "" {
log.Fatal("Provide a file to parse")
}
fmt.Println("Getting file")
names := make(chan string)
readerr := make(chan error)
done := make(chan bool)
go GetLine(*filename, names, readerr, done)
for {
select {
case name := <-names:
// Process each line
fmt.Println(name)
case err := <-readerr:
log.Fatal(err)
case <-done:
// close(names)
// close(readerr)
break
}
}
fmt.Println("Processing Complete")
}
func GetLine(filename string, names chan string, readerr chan error, done chan bool) {
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
names <- scanner.Text()
//fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
readerr <- err
}
done <- true
}
Was bekomme ich auf Laufen
Laufzeitfehler: fatal error: all goroutines are asleep - deadlock!
Was habe ich zu Fix Versuchte?
Nach this Antwort über die Fehlermeldung zu lesen, habe ich versucht, names
und readerr
in der letzten Klausel der select
Anweisung, um die Kanäle zu schließen, wie in den Kommentaren gezeigt. Das Programm stürzt jedoch weiterhin mit einer Protokollnachricht ab. Ich kann es nicht weiter beheben und würde mich über jede Hilfe freuen.
Ressourcen zum Lernen sind willkommen.
P.S: Ich bin relativ neu bei GoLang und lerne immer noch, wie man mit dem CSP-Modell der Parallelität in Go arbeitet. Tatsächlich ist dies mein erster Versuch, ein synchrones konkurrierendes Programm zu schreiben.
Die Ausgabe des Deadlock-Fehlers sollte Ihnen genau sagen, in welcher Zeile jede Goroutine steckt, was Ihnen helfen sollte, herauszufinden, warum das passiert. – Adrian
@Adrian Danke für die Antwort. Jetzt habe ich herausgefunden, dass das Problem mit der vollständigen Ausführung der'GetLine'Goroutine zusammenhängt, während die 'select' Anweisung immer noch erwartet, einen Wert zu erhalten. Daher wird dieser Fehler ausgelöst. Habe ich recht? –