Heim  >  Artikel  >  Backend-Entwicklung  >  Lesen mehrerer Rückgabewerte aus Goroutine

Lesen mehrerer Rückgabewerte aus Goroutine

PHPz
PHPznach vorne
2024-02-09 12:30:091073Durchsuche

从 goroutine 读取多个返回值

php Editor Apple Das Lesen mehrerer Rückgabewerte aus Goroutine ist eine übliche Operation in der Go-Sprache. Goroutine ist ein leichter Thread in der Go-Sprache, der eine gleichzeitige Ausführung erreichen kann. In einigen Fällen müssen wir den Rückgabewert von einer oder mehreren Goroutinen zur weiteren Verarbeitung abrufen. Dieser Vorgang kann durch die Verwendung von Kanälen erreicht werden, die einen wichtigen Mechanismus für die Kommunikation zwischen Goroutinen darstellen. Über Kanäle können wir Daten zwischen Goroutinen weitergeben und eine Synchronisierung und Kommunikation zwischen Coroutinen erreichen. In diesem Artikel werden wir die Tipps und Überlegungen zum Lesen mehrerer Rückgabewerte aus einer Goroutine detailliert beschreiben.

Frageninhalt

Ich versuche wc(1) in Go zu schreiben und versuche, Goroutinen zu verwenden, um eine große Anzahl von Eingabedateien effizienter zu berechnen. Mein Code funktioniert einwandfrei, aber ich habe Probleme beim Implementieren einer Möglichkeit, Statistiken für alle Go-Routinen zusammenzufassen. Wie kann ich Funktionsvariablen nlnwnc an main übergeben und dort aggregieren, nachdem alle Go-Routinen ihre Arbeit beendet haben?

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    ch := make(chan string)

    for _, arg := range os.Args[1:] {
        go wc(arg, ch)
    }
    for range os.Args[1:] {
        fmt.Println(<-ch)
    }
    // Todo: summarize results...
}

func wc(arg string, ch chan<- string) {
    nl, nw, nc := 0, 0, 0

    file, err := os.Open(arg)
    if err != nil {
        fmt.Println("Can't open file: %v", err)
    }
    defer file.Close()

    scan := bufio.NewScanner(file)
    for scan.Scan() {
        nl++

        line := scan.Text()
        words := bufio.NewScanner(strings.NewReader(line))
        words.Split(bufio.ScanWords)
        for words.Scan() {
            nw++
        }

        runes := bufio.NewReader(strings.NewReader(line))
        for {
            if _, _, err := runes.ReadRune(); err != nil {
                break
            } else {
                nc++
            }
        }
    }

    ch <- fmt.Sprintf("%8d%8d%8d", nl, nw, nc+nl)
}

Lösung

Du bist der Antwort nahe! Ich empfehle eine schnelle Umgestaltung, um Result 对象,这将允许轻松地在末尾添加它们(而不是使用字符串)。因此,您可以使用 chan 结果 而不是 chan string mit einer Nummer zurückzugeben.

Im Grunde führen Sie ein totalResult 变量,并且在迭代所有结果时,只需将 nlncnw Ergebnis ein, das zu dieser Gesamtvariablen addiert wird.

<code>package main

import (
    "fmt"
    "math/rand"
)

// define a struct to hold the result
type Result struct {
    nl int
    nw int
    nc int
}

// this is to be able to use fmt.Println(result)
func (r Result) String() string {
    return fmt.Sprintf("%8d%8d%8d", r.nl, r.nw, r.nc+r.nl)
}

func main() {
    ch := make(chan Result)

    for _, arg := range os.Args[1:] {
        go wc(arg, ch)
    }

    totalResult := Result{}

    for range os.Args[1:] {
        result := <-ch
        fmt.Println(result) // just for debugging

        // sum everything
        totalResult.nl += result.nl
        totalResult.nw += result.nw
        totalResult.nc += result.nc
    }

    fmt.Println("Total result:")
    fmt.Println(totalResult)
}

func wc(arg string, ch chan<- Result) {
    nl, nw, nc := 0, 0, 0

    // your logic to compute nl, nw, nc goes here

    ch <- Result{nl: nl, nw: nw, nc: nc + nl}
}
</code>

Sie sollten so etwas erhalten (mit 3 Dateien):

37      50    4753
      19     106     821
      47     255    3806
Total result:
     103     411    9380

Das obige ist der detaillierte Inhalt vonLesen mehrerer Rückgabewerte aus Goroutine. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen