GoLang之Concurrency順序管道模式

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

2013-12-14 wcdj


本文介紹go利用管道如何進行並發計算,需要注意go的管道是雙向的,而UNIX管道是單向的。

PS: 在測試時自己建立了一個尾碼為_test.go的檔案,build後會提示如下錯誤:

一句話解釋:在go中檔案名稱尾碼為_test.go的都是單元測試檔案。

具體可參考:http://segmentfault.com/q/1010000000159135


本例參考《go語言程式設計》第七章的一個例子,並添加了一些注釋。

package mainimport ("flag""fmt""log""os""path/filepath""runtime""strings")func main() {// Use all the machine's coresruntime.GOMAXPROCS(runtime.NumCPU())log.SetFlags(0)// 處理命令列參數algorithm, minSize, maxSize, suffixes, files := handleCommandLine()// 開始計算操作if algorithm == 1 {// 演算法1是並行計算, 通過建立各個的goroutine// step1: 先通過source函數處理檔案清單, 並把處理結果返回到管道裡// step2: 將符合尾碼的檔案放到管道裡// step3: 將符合大小的檔案放到管道裡// step4: 從管道擷取結果資料sink(filterSize(minSize, maxSize, filterSuffixes(suffixes, source(files))))} else {// 演算法2是串列計算channel1 := source(files)channel2 := filterSuffixes(suffixes, channel1)channel3 := filterSize(minSize, maxSize, channel2)sink(channel3)}}// 命令列參數解析操作func handleCommandLine() (algorithm int, minSize, maxSize int64,suffixes, files []string) {// 將命令列參數綁定到對應的變數中// algorithm預設為1flag.IntVar(&algorithm, "algorithm", 1, "1 or 2")// minSize和maxSize預設為-1, 表示沒有限制flag.Int64Var(&minSize, "min", -1,"minimum file size (-1 means no minimum)")flag.Int64Var(&maxSize, "max", -1,"maximum file size (-1 means no maximum)")// suffixes尾碼列表預設為空白var suffixesOpt *string = flag.String("suffixes", "","comma-separated list of file suffixes")// 命令列預先處理flag.Parse()if algorithm != 1 && algorithm != 2 {algorithm = 1}if minSize > maxSize && maxSize != -1 {// Fatalln is equivalent to Println() followed by a call to os.Exit(1)log.Fatalln("minimum size must be < maximum size")}// 將尾碼列表用逗號分隔, 返回suffixes尾碼切片suffixes = []string{}if *suffixesOpt != "" {suffixes = strings.Split(*suffixesOpt, ",")}// Args returns the non-flag command-line arguments// 認為非命令選項的參數全為檔案參數files = flag.Args()return algorithm, minSize, maxSize, suffixes, files}// 建立管道, 處理檔案清單並把結果返回到管道裡func source(files []string) <-chan string {out := make(chan string, 1000)go func() {for _, filename := range files {out <- filename}close(out)}()return out}// 將符合尾碼的檔案放到管道裡// 根據尾碼切片處理管道裡的檔案, 同樣再把結果返回到管道裡// make the buffer the same size as for files to maximize throughputfunc filterSuffixes(suffixes []string, in <-chan string) <-chan string {out := make(chan string, cap(in))go func() {for filename := range in {// 沒有限制尾碼的話, 則直接將檔案塞到管道裡if len(suffixes) == 0 {out <- filenamecontinue}// 擷取檔案清單的尾碼, 且全部轉換為小寫// Ext returns the file name extension used by path. The extension is the suffix beginning at the final dot in the final element of path; it is empty if there is no dotext := strings.ToLower(filepath.Ext(filename))for _, suffix := range suffixes {if ext == suffix {out <- filenamebreak}}}close(out)}()return out}// 將符合檔案大小的檔案放到管道裡// make the buffer the same size as for files to maximize throughputfunc filterSize(minimum, maximum int64, in <-chan string) <-chan string {out := make(chan string, cap(in))go func() {for filename := range in {// 對檔案大小沒有限制, 直接將檔案塞到管道裡if minimum == -1 && maximum == -1 {out <- filename // don't do a stat call it not neededcontinue}// 使用作業系統的介面擷取檔案大小等資訊// Stat returns a FileInfo describing the named file. If there is an error, it will be of type *PathError/*type FileInfo interface {        Name() string       // base name of the file        Size() int64        // length in bytes for regular files; system-dependent for others        Mode() FileMode     // file mode bits        ModTime() time.Time // modification time        IsDir() bool        // abbreviation for Mode().IsDir()        Sys() interface{}   // underlying data source (can return nil)}*/finfo, err := os.Stat(filename)if err != nil {continue // ignore files we can't process}size := finfo.Size()if (minimum == -1 || minimum > -1 && minimum <= size) &&(maximum == -1 || maximum > -1 && maximum >= size) {out <- filename}}close(out)}()return out}// 從管道擷取結果資料func sink(in <-chan string) {for filename := range in {fmt.Println(filename)}}/*output:mba:go gerryyang$ ./filter_t -min 1 -suffixes ".cpp" ../c++11/range_for.cpp ../c++11/test ../c++11/test.cpp routines.go../c++11/range_for.cpp../c++11/test.cppmba:go gerryyang$ ./filter_t -min 1 -max -2 -suffixes ".cpp" ../c++11/range_for.cpp ../c++11/test ../c++11/test.cpp routines.go jjjj minimum size must be < maximum size*/


在網上發現一個go的學習網站,有空可以逛下:http://blog.studygolang.com/





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.