Home >Backend Development >Golang >Reading multiple return values from goroutine
php Editor Apple Reading multiple return values from goroutine is a common operation in the Go language. Goroutine is a lightweight thread in the Go language that can achieve concurrent execution. In some cases, we need to get the return value from one or more goroutines for further processing. This operation can be achieved by using channels, which are an important mechanism for communication between goroutines. Through channels, we can pass data between goroutines and achieve synchronization and communication between coroutines. In this article, we will detail the tips and considerations on how to read multiple return values from a goroutine.
I'm trying to write wc(1) in Go, and I'm trying to use goroutines to compute a large number of input files more efficiently. My code works fine, but I'm having trouble implementing a way to summarize statistics for all go routines. How can I pass the function variables nl
, nw
, nc
to main and aggregate them there after all the go routines have finished their work?
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) }
You are close to the answer! I'd suggest a quick refactor to return a Result
object with numbers, which would allow adding them at the end easily (instead of using a string). Therefore, you can use chan result
instead of chan string
.
Basically, you can introduce a totalResult
variable and when iterating over all results, just add nl
, nc
and nw# The result of ## is added to this total variable.
<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>You should get something like this (containing 3 files):
37 50 4753 19 106 821 47 255 3806 Total result: 103 411 9380
The above is the detailed content of Reading multiple return values from goroutine. For more information, please follow other related articles on the PHP Chinese website!