php小編蘋果從goroutine讀取多個返回值是Go語言中的一種常見操作。Goroutine是Go語言中的輕量級線程,能夠實現并發執行。在某些情況下,我們需要從一個或多個goroutine中獲取返回值,以便進一步處理。這種操作可以通過使用通道(channel)來實現,通道是goroutine之間進行通信的重要機制。通過通道,我們可以在goroutine之間傳遞數據,實現協程之間的同步與通信。在本文中,我們將詳細介紹如何從goroutine讀取多個返回值的技巧和注意事項。
問題內容
我正在嘗試用 Go 編寫 wc(1),并且正在嘗試使用 goroutine 來更有效地計算大量輸入文件。我的代碼工作正常,但我很難實現一種方法來總結所有 go 例程的統計信息。如何將函數變量 nl
、nw
、nc
傳遞給 main,并在所有 go 例程完成工作后在那里匯總它們?
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) }
登錄后復制
解決方法
您已經接近答案了!我建議快速重構,返回帶有數字的 Result
對象,這將允許輕松地在末尾添加它們(而不是使用字符串)。因此,您可以使用 chan 結果
而不是 chan string
。
基本上,您可以引入一個 totalResult
變量,并且在迭代所有結果時,只需將 nl
、nc
和 nw
的結果添加到該總變量中。
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}
}
登錄后復制
您應該得到類似這樣的內容(包含 3 個文件):
37 50 4753 19 106 821 47 255 3806 Total result: 103 411 9380
登錄后復制